diff --git a/html/js/controllers/send_coins.js b/html/js/controllers/send_coins.js index 342b296..dd341b2 100644 --- a/html/js/controllers/send_coins.js +++ b/html/js/controllers/send_coins.js @@ -292,7 +292,7 @@ thinwalletCtrls.controller('SendCoinsCtrl', function($scope, $http, $q, AccountS var tx_hash = tx_h.hash; // work out per-kb fee for transaction var txBlobBytes = raw_tx.length / 2; - var numKB = Math.floor(txBlobBytes / 1024); + var numKB = Math.floor((txBlobBytes) / 1024); if (txBlobBytes % 1024) { numKB++; } @@ -482,7 +482,14 @@ thinwalletCtrls.controller('SendCoinsCtrl', function($scope, $http, $q, AccountS var splittedDsts = cnUtil.decompose_tx_destinations(dsts, rct); console.log('Decomposed destinations:'); cnUtil.printDsts(splittedDsts); - signed = cnUtil.create_transaction(AccountService.getPublicKeys(), AccountService.getSecretKeys(), splittedDsts, using_outs, mix_outs, mixin, neededFee, payment_id, pid_encrypt, realDestViewKey, 0, rct); + signed = cnUtil.create_transaction( + AccountService.getPublicKeys(), + AccountService.getSecretKeys(), + splittedDsts, using_outs, + mix_outs, mixin, neededFee, + payment_id, pid_encrypt, + realDestViewKey, 0, rct); + } catch (e) { deferred.reject("Failed to create transaction: " + e); return; diff --git a/sql/openmonero.sql b/sql/openmonero.sql index 7747cd8..5a14472 100644 --- a/sql/openmonero.sql +++ b/sql/openmonero.sql @@ -3,9 +3,9 @@ -- https://www.phpmyadmin.net/ -- -- Host: localhost --- Generation Time: Feb 12, 2017 at 04:17 AM +-- Generation Time: Feb 16, 2017 at 05:55 AM -- Server version: 10.1.21-MariaDB --- PHP Version: 7.1.1 +-- PHP Version: 7.1.2 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; @@ -116,6 +116,8 @@ CREATE TABLE `Transactions` ( `height` bigint(20) UNSIGNED NOT NULL DEFAULT '0', `spendable` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Has 10 blocks pasted since it was indexed?', `coinbase` tinyint(1) NOT NULL DEFAULT '0', + `is_rct` tinyint(1) NOT NULL DEFAULT '1', + `rct_type` int(4) NOT NULL DEFAULT '-1', `payment_id` varchar(64) NOT NULL DEFAULT '', `mixin` bigint(20) UNSIGNED NOT NULL DEFAULT '0', `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP @@ -173,17 +175,17 @@ ALTER TABLE `Transactions` -- AUTO_INCREMENT for table `Accounts` -- ALTER TABLE `Accounts` - MODIFY `id` bigint(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6; + MODIFY `id` bigint(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; -- -- AUTO_INCREMENT for table `Inputs` -- ALTER TABLE `Inputs` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=766; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=210; -- -- AUTO_INCREMENT for table `Outputs` -- ALTER TABLE `Outputs` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=384; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=297; -- -- AUTO_INCREMENT for table `Payments` -- @@ -193,7 +195,7 @@ ALTER TABLE `Payments` -- AUTO_INCREMENT for table `Transactions` -- ALTER TABLE `Transactions` - MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=701; + MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=389; -- -- Constraints for dumped tables -- diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index c5aaafa..d5229fd 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -690,5 +690,55 @@ CurrentBlockchainStatus::clean_search_thread_map() } +tuple +CurrentBlockchainStatus::construct_output_rct_field( + const uint64_t global_amount_index, + const uint64_t out_amount) +{ + + transaction random_output_tx; + uint64_t output_idx_in_tx; + + // we got random outputs, but now we need to get rct data of those + // outputs, because by default frontend created ringct txs. + + if (!CurrentBlockchainStatus::get_tx_with_output( + global_amount_index, out_amount, + random_output_tx, output_idx_in_tx)) + { + cerr << "cant get random output transaction" << endl; + return make_tuple(string {}, string {}, string {}); + } + + //cout << pod_to_hex(out.out_key) << endl; + //cout << pod_to_hex(get_transaction_hash(random_output_tx)) << endl; + //cout << output_idx_in_tx << endl; + + // placeholder variable for ringct outputs info + // that we need to save in database + string rtc_outpk; + string rtc_mask(64, '0'); + string rtc_amount(64, '0'); + + + if (random_output_tx.version > 1 && !is_coinbase(random_output_tx)) + { + rtc_outpk = pod_to_hex(random_output_tx.rct_signatures.outPk[output_idx_in_tx].mask); + rtc_mask = pod_to_hex(random_output_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask); + rtc_amount = pod_to_hex(random_output_tx.rct_signatures.ecdhInfo[output_idx_in_tx].amount); + } + else + { + // for non ringct txs, we need to take it rct amount acommitment + // and sent to the frontend. + + output_data_t od = get_output_key(out_amount, global_amount_index); + + rtc_outpk = pod_to_hex(od.commitment); + } + + return make_tuple(rtc_outpk, rtc_mask, rtc_amount); +}; + } \ No newline at end of file diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 73dde63..b814a64 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -168,6 +168,15 @@ struct CurrentBlockchainStatus static void clean_search_thread_map(); + /* + * The frontend requires rct field to work + * the filed consisitct of rct_pk, mask, and amount. + */ + static tuple + construct_output_rct_field( + const uint64_t global_amount_index, + const uint64_t out_amount); + }; diff --git a/src/MySqlAccounts.cpp b/src/MySqlAccounts.cpp index 75bad6b..ac66800 100644 --- a/src/MySqlAccounts.cpp +++ b/src/MySqlAccounts.cpp @@ -396,6 +396,8 @@ MysqlTransactions::insert(const XmrTransaction& tx_data) tx_data.unlock_time, tx_data.height, tx_data.coinbase, + tx_data.is_rct, + tx_data.rct_type, tx_data.spendable, tx_data.payment_id, tx_data.mixin, diff --git a/src/OutputInputIdentification.cpp b/src/OutputInputIdentification.cpp index 2bfbb09..53f2d73 100644 --- a/src/OutputInputIdentification.cpp +++ b/src/OutputInputIdentification.cpp @@ -28,6 +28,14 @@ OutputInputIdentification::OutputInputIdentification( tx_is_coinbase = is_coinbase(*tx); + is_rct = (tx->version == 2); + + if (is_rct) + { + rct_type = tx->rct_signatures.type; + } + + if (!generate_key_derivation(tx_pub_key, *viewkey, derivation)) { cerr << "Cant get derived key for: " << "\n" diff --git a/src/OutputInputIdentification.h b/src/OutputInputIdentification.h index 0dfda6a..049d4e8 100644 --- a/src/OutputInputIdentification.h +++ b/src/OutputInputIdentification.h @@ -79,6 +79,9 @@ public: bool tx_is_coinbase; + bool is_rct; + uint8_t rct_type; + uint64_t mixin_no; // for each output, in a tx, check if it belongs diff --git a/src/TxSearch.cpp b/src/TxSearch.cpp index f254309..7f8f0a9 100644 --- a/src/TxSearch.cpp +++ b/src/TxSearch.cpp @@ -206,6 +206,8 @@ TxSearch::search() tx_data.height = searched_blk_no; tx_data.coinbase = oi_identification.tx_is_coinbase; + tx_data.is_rct = oi_identification.is_rct; + tx_data.rct_type = oi_identification.rct_type; tx_data.spendable = is_spendable; tx_data.payment_id = CurrentBlockchainStatus::get_payment_id_as_string(tx); tx_data.mixin = oi_identification.mixin_no; @@ -364,6 +366,8 @@ TxSearch::search() // that we can spend tx_data.height = searched_blk_no; tx_data.coinbase = oi_identification.tx_is_coinbase; + tx_data.is_rct = oi_identification.is_rct; + tx_data.rct_type = oi_identification.rct_type; tx_data.spendable = is_spendable; tx_data.payment_id = CurrentBlockchainStatus::get_payment_id_as_string(tx); tx_data.mixin = get_mixin_no(tx) - 1; @@ -527,6 +531,8 @@ TxSearch::find_txs_in_mempool( // it shows unconfirmed message. j_tx["payment_id"] = CurrentBlockchainStatus::get_payment_id_as_string(tx); j_tx["coinbase"] = false; // mempool tx are not coinbase, so always false + j_tx["is_rct"] = oi_identification.is_rct; + j_tx["rct_type"] = oi_identification.rct_type; j_tx["mixin"] = get_mixin_no(tx) - 1; j_tx["mempool"] = true; @@ -618,6 +624,8 @@ TxSearch::find_txs_in_mempool( // it shows unconfirmed message. j_tx["payment_id"] = CurrentBlockchainStatus::get_payment_id_as_string(tx); j_tx["coinbase"] = false; // mempool tx are not coinbase, so always false + j_tx["is_rct"] = oi_identification.is_rct; + j_tx["rct_type"] = oi_identification.rct_type; j_tx["mixin"] = get_mixin_no(tx) - 1; j_tx["mempool"] = true; j_tx["spent_outputs"] = spend_keys; diff --git a/src/YourMoneroRequests.cpp b/src/YourMoneroRequests.cpp index ed1a6af..6c887b4 100644 --- a/src/YourMoneroRequests.cpp +++ b/src/YourMoneroRequests.cpp @@ -253,8 +253,8 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B for (json& j_tx: j_mempool_tx) { - //cout << "mempool j_tx[\"total_received\"]: " - // << j_tx["total_received"] << endl; + cout << "mempool j_tx[\"total_received\"]: " + << j_tx["total_received"] << endl; j_tx["id"] = ++last_tx_id_db; total_received_mempool += j_tx["total_received"].get(); @@ -445,12 +445,38 @@ YourMoneroRequests::get_unspent_outs(const shared_ptr< Session > session, const { for (XmrOutput &out: outs) { + // need to check for rct commintment + // coinbase ringct txs dont have + // rct filed in them. Thus + // we need to make them. + + uint64_t global_amount_index = out.global_index; + + uint64_t out_amount {out.amount}; + + // but if ringct tx, set it amount to zero + // as in Outputs table we store decoded outputs amounts + if (tx.is_rct) + { + out_amount = 0; + } + + tuple + rct_field = CurrentBlockchainStatus::construct_output_rct_field( + global_amount_index, out_amount); + + string rct = std::get<0>(rct_field) // rct_pk + + std::get<1>(rct_field) // rct_mask + + std::get<2>(rct_field); // rct_amount + + //string rct = out.get_rct(); + json j_out{ {"amount", out.amount}, {"public_key", out.out_pub_key}, {"index", out.out_index}, {"global_index", out.global_index}, - {"rct" , out.get_rct()}, + {"rct" , rct}, {"tx_id", out.tx_id}, {"tx_hash", tx.hash}, {"tx_prefix_hash", tx.prefix_hash}, @@ -533,56 +559,18 @@ YourMoneroRequests::get_random_outs(const shared_ptr< Session > session, const B { uint64_t global_amount_index = out.global_amount_index; - transaction random_output_tx; - uint64_t output_idx_in_tx; - - // we got random outputs, but now we need to get rct data of those - // outputs, because by default frontend created ringct txs. - - if (!CurrentBlockchainStatus::get_tx_with_output( - global_amount_index, outs.amount, - random_output_tx, output_idx_in_tx)) - { - cerr << "cant get random output transaction" << endl; - break; - } - - //cout << pod_to_hex(out.out_key) << endl; - //cout << pod_to_hex(get_transaction_hash(random_output_tx)) << endl; - //cout << output_idx_in_tx << endl; - - // placeholder variable for ringct outputs info - // that we need to save in database - string rtc_outpk; - string rtc_mask(64, '0'); - string rtc_amount(64, '0'); + tuple + rct_field = CurrentBlockchainStatus::construct_output_rct_field( + global_amount_index, outs.amount); json out_details { {"global_index", out.global_amount_index}, - {"public_key" , pod_to_hex(out.out_key)} + {"public_key" , pod_to_hex(out.out_key)}, + {"rct" , std::get<0>(rct_field) // rct_pk + + std::get<1>(rct_field) // rct_mask + + std::get<2>(rct_field)} // rct_amount }; - - if (random_output_tx.version > 1 && !is_coinbase(random_output_tx)) - { - rtc_outpk = pod_to_hex(random_output_tx.rct_signatures.outPk[output_idx_in_tx].mask); - rtc_mask = pod_to_hex(random_output_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask); - rtc_amount = pod_to_hex(random_output_tx.rct_signatures.ecdhInfo[output_idx_in_tx].amount); - - out_details["rct"]= rtc_outpk + rtc_mask + rtc_amount; - } - else - { - // for non ringct txs, we need to take it rct amount acommitment - // and sent to the frontend. - - output_data_t od = CurrentBlockchainStatus::get_output_key(outs.amount, global_amount_index); - - rtc_outpk = pod_to_hex(od.commitment); - } - - out_details["rct"] = rtc_outpk + rtc_mask + rtc_amount; - j_outputs.push_back(out_details); } // for (const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& out: outs.outs) diff --git a/src/ssqlses.cpp b/src/ssqlses.cpp index eadd21b..a71d32f 100644 --- a/src/ssqlses.cpp +++ b/src/ssqlses.cpp @@ -45,6 +45,8 @@ XmrTransaction::to_json() const {"payment_id" , payment_id}, {"unlock_time" , unlock_time}, {"coinbase" , bool {coinbase}}, + {"is_rct" , bool {is_rct}}, + {"rct_type" , rct_type}, {"spendable" , bool {spendable}}, {"mixin" , mixin}, {"timestamp" , timestamp} diff --git a/src/ssqlses.h b/src/ssqlses.h index 5d8eecc..68e2323 100644 --- a/src/ssqlses.h +++ b/src/ssqlses.h @@ -58,7 +58,7 @@ struct XmrAccount : public Accounts }; -sql_create_13(Transactions, 1, 2, +sql_create_15(Transactions, 1, 2, sql_bigint_unsigned, id, sql_varchar , hash, sql_varchar , prefix_hash, @@ -68,6 +68,8 @@ sql_create_13(Transactions, 1, 2, sql_bigint_unsigned, unlock_time, sql_bigint_unsigned, height, sql_bool , coinbase, + sql_bool , is_rct, + sql_int , rct_type, sql_bool , spendable, sql_varchar , payment_id, sql_bigint_unsigned, mixin, @@ -96,12 +98,14 @@ struct XmrTransaction : public Transactions static constexpr const char* INSERT_STMT = R"( INSERT IGNORE INTO `Transactions` (`hash`, `prefix_hash`, `account_id`, `total_received`, `total_sent`, `unlock_time`, - `height`, `coinbase`, `spendable`, + `height`, `coinbase`, `is_rct`, `rct_type`, + `spendable`, `payment_id`, `mixin`, `timestamp`) VALUES (%0q, %1q, %2q, %3q, %4q, %5q, - %6q, %7q, %8q, - %9q, %10q, %11q); + %6q, %7q, %8q, %9q, + %10q, + %11q, %12q, %13q); )"; static constexpr const char* MARK_AS_SPENDABLE_STMT = R"(