From d35584aa3015b9d9314c563368ca53c27cfd6d6b Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 11:39:45 +0200 Subject: [PATCH 01/11] Fixing mixin pt 1, almost working :) Requies daemon's get_random_outs outs to be not bin but json --- src/config.ts | 2 +- src/model/Cn.ts | 30 +++++++------ src/model/TransactionsExplorer.ts | 35 ++++++--------- src/model/blockchain/BlockchainExplorer.ts | 7 ++- .../blockchain/BlockchainExplorerRPCDaemon.ts | 45 +++++++++++++++---- src/pages/send.ts | 6 +-- 6 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/config.ts b/src/config.ts index 11ca6cf5..7beea641 100644 --- a/src/config.ts +++ b/src/config.ts @@ -25,7 +25,7 @@ global.config = { coinFee: new JSBigInt('10000000000'), feePerKB: new JSBigInt('10000000000'), //for testnet its not used, as fee is dynamic. dustThreshold: new JSBigInt('100000000'),//used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold - defaultMixin: 0, // default value mixin + defaultMixin: 3, // default value mixin idleTimeout: 30, idleWarningDuration: 20, diff --git a/src/model/Cn.ts b/src/model/Cn.ts index 73ff11a1..eb213dcb 100644 --- a/src/model/Cn.ts +++ b/src/model/Cn.ts @@ -2161,9 +2161,9 @@ export namespace CnTransactions{ tx_pub_key:string, }[], mix_outs:{ - outputs:{ - public_key:string, - global_index:number + outs:{ + out_key:string, + global_amount_index:number }[], amount:0 }[] = [], @@ -2183,7 +2183,7 @@ export namespace CnTransactions{ throw 'Wrong number of mix outs provided (' + outputs.length + ' outputs, ' + mix_outs.length + ' mix outs)'; } for (i = 0; i < mix_outs.length; i++) { - if ((mix_outs[i].outputs || []).length < fake_outputs_count) { + if ((mix_outs[i].outs || []).length < fake_outputs_count) { throw 'Not enough outputs to mix with'; } } @@ -2232,25 +2232,27 @@ export namespace CnTransactions{ src.amount = new JSBigInt(outputs[i].amount).toString(); if (mix_outs.length !== 0) { // Sort fake outputs by global index - console.log('mix outs before sort',mix_outs[i].outputs); - mix_outs[i].outputs.sort(function(a, b) { - return new JSBigInt(a.global_index).compare(b.global_index); + console.log('mix outs before sort',mix_outs[i].outs); + mix_outs[i].outs.sort(function(a, b) { + return new JSBigInt(a.global_amount_index).compare(b.global_amount_index); }); j = 0; - console.log('mix outs sorted',mix_outs[i].outputs); + console.log('mix outs sorted',mix_outs[i].outs); - while ((src.outputs.length < fake_outputs_count) && (j < mix_outs[i].outputs.length)) { - let out = mix_outs[i].outputs[j]; - console.log('chekcing mixin',out, outputs[i]); - if (out.global_index === outputs[i].global_index) { + while ((src.outputs.length < fake_outputs_count) && (j < mix_outs[i].outs.length)) { + let out = mix_outs[i].outs[j]; + console.log('chekcing mixin'); + console.log("out: ", out); + console.log("output ", i, ": ", outputs[i]); + if (out.global_amount_index === outputs[i].global_index) { console.log('got mixin the same as output, skipping'); j++; continue; } let oe : Output = { - index:out.global_index.toString(), - key:out.public_key, + index:out.global_amount_index.toString(), + key:out.out_key, commit:'' }; /* diff --git a/src/model/TransactionsExplorer.ts b/src/model/TransactionsExplorer.ts index 43e9d131..2289afed 100644 --- a/src/model/TransactionsExplorer.ts +++ b/src/model/TransactionsExplorer.ts @@ -35,7 +35,7 @@ import {Transaction, TransactionIn, TransactionOut} from "./Transaction"; import {Wallet} from "./Wallet"; import {MathUtil} from "./MathUtil"; import {Cn, CnNativeBride, CnRandom, CnTransactions, CnUtils} from "./Cn"; -import {RawDaemon_Transaction} from "./blockchain/BlockchainExplorer"; +import {RawDaemon_Transaction, RawDaemon_Out} from "./blockchain/BlockchainExplorer"; import hextobin = CnUtils.hextobin; export const TX_EXTRA_PADDING_MAX_COUNT = 255; @@ -470,7 +470,7 @@ export class TransactionsExplorer { userPaymentId: string = '', wallet: Wallet, blockchainHeight: number, - obtainMixOutsCallback: (quantity: number) => Promise, + obtainMixOutsCallback: (amounts: number[], numberOuts: number) => Promise, confirmCallback: (amount: number, feesAmount: number) => Promise, mixin: number = config.defaultMixin): Promise<{ raw: { hash: string, prvkey: string, raw: string }, signed: any }> { @@ -559,17 +559,8 @@ export class TransactionsExplorer { //console.log("Using output: " + out.amount + " - " + JSON.stringify(out)); } - const calculateFeeWithBytes = function (fee_per_kb: number, bytes: number, fee_multiplier: number) { - let kB = (bytes + 1023) / 1024; - return kB * fee_per_kb * fee_multiplier; - }; - console.log("Selected outs:", usingOuts); - if (neededFee < 10000000) { - neededFee = 10000000; - } - console.log('using amount of ' + usingOuts_amount + ' for sending ' + totalAmountWithoutFee + ' with fees of ' + (neededFee / Math.pow(10, config.coinUnitPlaces)) + ' KRB'); confirmCallback(totalAmountWithoutFee, neededFee).then(function () { if (usingOuts_amount.compare(totalAmount) < 0) { @@ -584,12 +575,14 @@ export class TransactionsExplorer { let changeAmount = usingOuts_amount.subtract(totalAmount); //add entire change for rct console.log("1) Sending change of " + Cn.formatMoneySymbol(changeAmount) - + " to " /*+ AccountService.getAddress()*/); + + " to " + wallet.getPublicAddress()); dsts.push({ address: wallet.getPublicAddress(), amount: changeAmount }); - } else if (usingOuts_amount.compare(totalAmount) === 0) { + } /* + // not applicable for Karbo + else if (usingOuts_amount.compare(totalAmount) === 0) { //create random destination to keep 2 outputs always in case of 0 change let fakeAddress = Cn.create_address(CnRandom.random_scalar()).public_addr; console.log("Sending 0 KRB to a fake address to keep tx uniform (no change exists): " + fakeAddress); @@ -597,20 +590,20 @@ export class TransactionsExplorer { address: fakeAddress, amount: 0 }); - } + }*/ console.log('destinations', dsts); - let amounts: string[] = []; + let amounts: number[] = []; for (let l = 0; l < usingOuts.length; l++) { - amounts.push(usingOuts[l].amount.toString()); + amounts.push(usingOuts[l].amount); } - obtainMixOutsCallback(amounts.length * (mixin + 1)).then(function (lotsMixOuts: any[]) { - console.log('------------------------------mix_outs', lotsMixOuts); + obtainMixOutsCallback(amounts, (mixin + 1)).then(function (lotsMixOuts: any[]) { + console.log('------------------------------mix_outs'); console.log('amounts', amounts); console.log('lots_mix_outs', lotsMixOuts); - let mix_outs = []; + /*let mix_outs = []; let iMixOutsIndexes = 0; for (let amount of amounts) { let localMixOuts = []; @@ -624,9 +617,9 @@ export class TransactionsExplorer { amount: 0 }); } - console.log('mix_outs', mix_outs); + console.log('mix_outs', mix_outs);*/ - TransactionsExplorer.createRawTx(dsts, wallet, false, usingOuts, pid_encrypt, mix_outs, mixin, neededFee, paymentId).then(function (data: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { + TransactionsExplorer.createRawTx(dsts, wallet, false, usingOuts, pid_encrypt, /*mix_outs*/lotsMixOuts, mixin, neededFee, paymentId).then(function (data: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { resolve(data); }).catch(function (e) { reject(e); diff --git a/src/model/blockchain/BlockchainExplorer.ts b/src/model/blockchain/BlockchainExplorer.ts index 922ed34a..dc8f1b37 100644 --- a/src/model/blockchain/BlockchainExplorer.ts +++ b/src/model/blockchain/BlockchainExplorer.ts @@ -51,6 +51,11 @@ export type RemoteNodeInformation = { status: string }; +export type RawDaemon_Out = { + global_amount_index: number, + out_key: string +} + export interface BlockchainExplorer { resolveOpenAlias(str: string): Promise<{ address: string, name: string | null }>; @@ -66,7 +71,7 @@ export interface BlockchainExplorer { sendRawTx(rawTx: string): Promise; - getRandomOuts(numberOuts: number): Promise; + getRandomOuts(amounts: number[], nbOutsNeeded: number): Promise; getNetworkInfo(): Promise; diff --git a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts index eed71317..8904bf99 100644 --- a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts +++ b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts @@ -13,7 +13,7 @@ * 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. */ -import {BlockchainExplorer, NetworkInfo, RawDaemon_Transaction, RemoteNodeInformation} from "./BlockchainExplorer"; +import {BlockchainExplorer, NetworkInfo, RawDaemon_Transaction, RawDaemon_Out, RemoteNodeInformation} from "./BlockchainExplorer"; import {Wallet} from "../Wallet"; import {MathUtil} from "../MathUtil"; import {CnTransactions, CnUtils} from "../Cn"; @@ -247,9 +247,37 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { }); } - existingOuts: any[] = []; + getRandomOuts(amounts: number[], nbOutsNeeded: number): Promise { - getRandomOuts(nbOutsNeeded: number, initialCall = true): Promise { + //let selectedOuts = []; + + return this.makeRequest('POST', 'getrandom_outs', { + amounts: amounts, + outs_count: nbOutsNeeded + }).then((response: { + status: 'OK' | 'string', + outs: { global_amount_index: number, out_key: string }[] + }) => { + + + if (response.status !== 'OK') throw 'invalid_getrandom_outs_answer'; + + if (response.outs.length > 0) { + + //selectedOuts = response.outs; + + console.log("Got random outs: "); + + console.log(response.outs); + + + } + + return response.outs; + }); + + +/* let self = this; if (initialCall) { self.existingOuts = []; @@ -305,25 +333,24 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { } for (let output_idx_in_tx = 0; output_idx_in_tx < tx.vout.length; ++output_idx_in_tx) { - let rct = null; + //let rct = null; let globalIndex = output_idx_in_tx; if (typeof tx.global_index_start !== 'undefined' && typeof tx.output_indexes !== 'undefined') { globalIndex = tx.output_indexes[output_idx_in_tx]; } - if (tx.vout[output_idx_in_tx].amount !== 0) {//check if miner tx + /*if (tx.vout[output_idx_in_tx].amount !== 0) {//check if miner tx rct = CnTransactions.zeroCommit(CnUtils.d2s(tx.vout[output_idx_in_tx].amount)); } else { let rtcOutPk = tx.rct_signatures.outPk[output_idx_in_tx]; let rtcMask = tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask; let rtcAmount = tx.rct_signatures.ecdhInfo[output_idx_in_tx].amount; rct = rtcOutPk + rtcMask + rtcAmount; - } + }* / let newOut = { - rct: rct, + //rct: rct, public_key: tx.vout[output_idx_in_tx].target.data.key, global_index: globalIndex, - // global_index: count, }; if (typeof txCandidates[tx.height] === 'undefined') txCandidates[tx.height] = []; txCandidates[tx.height].push(newOut); @@ -344,7 +371,7 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { return selectedOuts; }); - }); + });*/ } sendRawTx(rawTx: string) { diff --git a/src/pages/send.ts b/src/pages/send.ts index f3d3c6b0..79dcf3fc 100644 --- a/src/pages/send.ts +++ b/src/pages/send.ts @@ -24,7 +24,7 @@ import {QRReader} from "../model/QRReader"; import {AppState} from "../model/AppState"; import {BlockchainExplorerProvider} from "../providers/BlockchainExplorerProvider"; import {NdefMessage, Nfc} from "../model/Nfc"; -import {BlockchainExplorer} from "../model/blockchain/BlockchainExplorer"; +import {BlockchainExplorer, RawDaemon_Out} from "../model/blockchain/BlockchainExplorer"; import {Cn} from "../model/Cn"; import {WalletWatchdog} from "../model/WalletWatchdog"; @@ -245,8 +245,8 @@ class SendView extends DestructableView { } }); TransactionsExplorer.createTx([{address: destinationAddress, amount: amountToSend}], self.paymentId, wallet, blockchainHeight, - function (numberOuts: number): Promise { - return blockchainExplorer.getRandomOuts(numberOuts); + function (amounts: number[], numberOuts: number): Promise { + return blockchainExplorer.getRandomOuts(amounts, numberOuts); } , function (amount: number, feesAmount: number): Promise { if (amount + feesAmount > wallet.unlockedAmount(blockchainHeight)) { From c6eecf5183b070f679fa2f38fa98e08d93d0397c Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 14:44:29 +0200 Subject: [PATCH 02/11] This way it seems to be sending txs with mixin successfully --- src/model/Cn.ts | 16 ++++++++-------- src/model/blockchain/BlockchainExplorer.ts | 4 ++-- .../blockchain/BlockchainExplorerRPCDaemon.ts | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/model/Cn.ts b/src/model/Cn.ts index eb213dcb..42839485 100644 --- a/src/model/Cn.ts +++ b/src/model/Cn.ts @@ -2162,8 +2162,8 @@ export namespace CnTransactions{ }[], mix_outs:{ outs:{ - out_key:string, - global_amount_index:number + public_key:string, + global_index:number }[], amount:0 }[] = [], @@ -2230,11 +2230,11 @@ export namespace CnTransactions{ } }; src.amount = new JSBigInt(outputs[i].amount).toString(); - if (mix_outs.length !== 0) { + if (mix_outs.length !== 0) { // if mixin // Sort fake outputs by global index console.log('mix outs before sort',mix_outs[i].outs); mix_outs[i].outs.sort(function(a, b) { - return new JSBigInt(a.global_amount_index).compare(b.global_amount_index); + return new JSBigInt(a.global_index).compare(b.global_index); }); j = 0; @@ -2245,14 +2245,14 @@ export namespace CnTransactions{ console.log('chekcing mixin'); console.log("out: ", out); console.log("output ", i, ": ", outputs[i]); - if (out.global_amount_index === outputs[i].global_index) { + if (out.global_index === outputs[i].global_index) { console.log('got mixin the same as output, skipping'); j++; continue; } let oe : Output = { - index:out.global_amount_index.toString(), - key:out.out_key, + index:out.global_index.toString(), + key:out.public_key, commit:'' }; /* @@ -2269,7 +2269,7 @@ export namespace CnTransactions{ src.outputs.push(oe); j++; } - } + } // end of if mixin let real_oe = { index:new JSBigInt(outputs[i].global_index || 0).toString(), key:outputs[i].public_key, diff --git a/src/model/blockchain/BlockchainExplorer.ts b/src/model/blockchain/BlockchainExplorer.ts index dc8f1b37..89c3c4e4 100644 --- a/src/model/blockchain/BlockchainExplorer.ts +++ b/src/model/blockchain/BlockchainExplorer.ts @@ -52,8 +52,8 @@ export type RemoteNodeInformation = { }; export type RawDaemon_Out = { - global_amount_index: number, - out_key: string + global_index: number, + public_key: string } export interface BlockchainExplorer { diff --git a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts index 8904bf99..f64fad83 100644 --- a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts +++ b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts @@ -256,7 +256,7 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { outs_count: nbOutsNeeded }).then((response: { status: 'OK' | 'string', - outs: { global_amount_index: number, out_key: string }[] + outs: { global_index: number, public_key: string }[] }) => { From 7aa650cd93e38940a05c1bc49d368f5fb9cf19ad Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 20:14:42 +0200 Subject: [PATCH 03/11] Remove unneeded code --- .../blockchain/BlockchainExplorerRPCDaemon.ts | 97 ------------------- 1 file changed, 97 deletions(-) diff --git a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts index f64fad83..d3bab609 100644 --- a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts +++ b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts @@ -275,103 +275,6 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { return response.outs; }); - - -/* - let self = this; - if (initialCall) { - self.existingOuts = []; - } - - return this.getHeight().then(function (height: number) { - let txs: RawDaemon_Transaction[] = []; - let promiseGetCompressedBlocks: Promise = Promise.resolve(); - - let randomBlocksIndexesToGet: number[] = []; - let numOuts = height; - - let compressedBlocksToGet: { [key: string]: boolean } = {}; - - console.log('Requires ' + nbOutsNeeded + ' outs'); - - //select blocks for the final mixin. selection is made with a triangular selection - for (let i = 0; i < nbOutsNeeded; ++i) { - let selectedIndex: number = -1; - do { - selectedIndex = MathUtil.randomTriangularSimplified(numOuts); - if (selectedIndex >= height - config.txCoinbaseMinConfirms) - selectedIndex = -1; - } while (selectedIndex === -1 || randomBlocksIndexesToGet.indexOf(selectedIndex) !== -1); - randomBlocksIndexesToGet.push(selectedIndex); - - compressedBlocksToGet[Math.floor(selectedIndex / 100) * 100] = true; - } - - console.log('Random blocks required: ', randomBlocksIndexesToGet); - console.log('Blocks to get for outputs selections:', compressedBlocksToGet); - - //load compressed blocks (100 blocks) containing the blocks referred by their index - for (let compressedBlock in compressedBlocksToGet) { - promiseGetCompressedBlocks = promiseGetCompressedBlocks.then(() => { - return self.getTransactionsForBlocks(parseInt(compressedBlock), Math.min(parseInt(compressedBlock) + 99, height - config.txCoinbaseMinConfirms), false).then(function (rawTransactions: RawDaemon_Transaction[]) { - txs.push.apply(txs, rawTransactions); - }); - }); - } - - return promiseGetCompressedBlocks.then(function () { - console.log('txs selected for outputs: ', txs); - let txCandidates: any = {}; - for (let iOut = 0; iOut < txs.length; ++iOut) { - let tx = txs[iOut]; - - if ( - (typeof tx.height !== 'undefined' && randomBlocksIndexesToGet.indexOf(tx.height) === -1) || - typeof tx.height === 'undefined' - ) { - continue; - } - - for (let output_idx_in_tx = 0; output_idx_in_tx < tx.vout.length; ++output_idx_in_tx) { - //let rct = null; - let globalIndex = output_idx_in_tx; - if (typeof tx.global_index_start !== 'undefined' && typeof tx.output_indexes !== 'undefined') { - globalIndex = tx.output_indexes[output_idx_in_tx]; - } - /*if (tx.vout[output_idx_in_tx].amount !== 0) {//check if miner tx - rct = CnTransactions.zeroCommit(CnUtils.d2s(tx.vout[output_idx_in_tx].amount)); - } else { - let rtcOutPk = tx.rct_signatures.outPk[output_idx_in_tx]; - let rtcMask = tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask; - let rtcAmount = tx.rct_signatures.ecdhInfo[output_idx_in_tx].amount; - rct = rtcOutPk + rtcMask + rtcAmount; - }* / - - let newOut = { - //rct: rct, - public_key: tx.vout[output_idx_in_tx].target.data.key, - global_index: globalIndex, - }; - if (typeof txCandidates[tx.height] === 'undefined') txCandidates[tx.height] = []; - txCandidates[tx.height].push(newOut); - - } - } - - console.log(txCandidates); - - let selectedOuts = []; - for (let txsOutsHeight in txCandidates) { - let outIndexSelect = MathUtil.getRandomInt(0, txCandidates[txsOutsHeight].length - 1); - console.log('select ' + outIndexSelect + ' for ' + txsOutsHeight + ' with length of ' + txCandidates[txsOutsHeight].length); - selectedOuts.push(txCandidates[txsOutsHeight][outIndexSelect]); - } - - console.log(selectedOuts); - - return selectedOuts; - }); - });*/ } sendRawTx(rawTx: string) { From 53c6da36a3d68fab2c6ac472f7c83bd267683f1c Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 20:16:48 +0200 Subject: [PATCH 04/11] Remove this unneeded code as well --- src/model/TransactionsExplorer.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/model/TransactionsExplorer.ts b/src/model/TransactionsExplorer.ts index 2289afed..297bfa2e 100644 --- a/src/model/TransactionsExplorer.ts +++ b/src/model/TransactionsExplorer.ts @@ -603,22 +603,6 @@ export class TransactionsExplorer { console.log('amounts', amounts); console.log('lots_mix_outs', lotsMixOuts); - /*let mix_outs = []; - let iMixOutsIndexes = 0; - for (let amount of amounts) { - let localMixOuts = []; - for (let i = 0; i < mixin + 1; ++i) { - localMixOuts.push(lotsMixOuts[iMixOutsIndexes]); - ++iMixOutsIndexes; - } - localMixOuts.sort().reverse(); - mix_outs.push({ - outputs: localMixOuts.slice(), - amount: 0 - }); - } - console.log('mix_outs', mix_outs);*/ - TransactionsExplorer.createRawTx(dsts, wallet, false, usingOuts, pid_encrypt, /*mix_outs*/lotsMixOuts, mixin, neededFee, paymentId).then(function (data: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { resolve(data); }).catch(function (e) { From 3d9f12f3223b2f550b55bb20e67227c97bc8fa0a Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 20:18:36 +0200 Subject: [PATCH 05/11] This is the last time --- src/model/blockchain/BlockchainExplorerRPCDaemon.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts index d3bab609..fd5ecb24 100644 --- a/src/model/blockchain/BlockchainExplorerRPCDaemon.ts +++ b/src/model/blockchain/BlockchainExplorerRPCDaemon.ts @@ -248,9 +248,6 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { } getRandomOuts(amounts: number[], nbOutsNeeded: number): Promise { - - //let selectedOuts = []; - return this.makeRequest('POST', 'getrandom_outs', { amounts: amounts, outs_count: nbOutsNeeded @@ -258,19 +255,10 @@ export class BlockchainExplorerRpcDaemon implements BlockchainExplorer { status: 'OK' | 'string', outs: { global_index: number, public_key: string }[] }) => { - - if (response.status !== 'OK') throw 'invalid_getrandom_outs_answer'; - if (response.outs.length > 0) { - - //selectedOuts = response.outs; - console.log("Got random outs: "); - console.log(response.outs); - - } return response.outs; From 6b8465f87f9c865a0f7daa9090efc9fef2b5a363 Mon Sep 17 00:00:00 2001 From: aiwe Date: Mon, 14 Feb 2022 22:34:02 +0200 Subject: [PATCH 06/11] Add mixin field to send with set mixin --- src/pages/send.html | 5 +++++ src/pages/send.ts | 15 ++++++++++++++- src/translations/en.json | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/pages/send.html b/src/pages/send.html index e016924c..1f7560b8 100644 --- a/src/pages/send.html +++ b/src/pages/send.html @@ -52,6 +52,11 @@

{{ $t("sendPage.qrCodeScanning.explication") }}

+
+ + +
+
diff --git a/src/pages/send.ts b/src/pages/send.ts index 79dcf3fc..f873cd08 100644 --- a/src/pages/send.ts +++ b/src/pages/send.ts @@ -42,6 +42,8 @@ class SendView extends DestructableView { @VueVar(true) amountToSendValid !: boolean; @VueVar('') paymentId !: string; @VueVar(true) paymentIdValid !: boolean; + @VueVar(3) mixIn !: number; + @VueVar(true) mixinIdValid !: boolean; @VueVar(null) domainAliasAddress !: string | null; @VueVar(null) txDestinationName !: string | null; @@ -290,7 +292,8 @@ class SendView extends DestructableView { }).catch(reject); }, 1); }); - }).then(function (rawTxData: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { + }, + self.mixIn).then(function (rawTxData: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { blockchainExplorer.sendRawTx(rawTxData.raw.raw).then(function () { //save the tx private key wallet.addTxPrivateKeyWithTxHash(rawTxData.raw.hash, rawTxData.raw.prvkey); @@ -424,6 +427,16 @@ class SendView extends DestructableView { } } + @VueWatched() + mixinIsValid() { + try { + if (this.mixIn > 10 || this.mixIn < 0 || this.mixIn === 1 || this.mixIn === 2) + this.mixinIdValid = false; + + } catch (e) { + this.mixinIdValid = false; + } + } } diff --git a/src/translations/en.json b/src/translations/en.json index ac480f9e..167e0e56 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -230,6 +230,9 @@ "label":"Payment ID (optional)", "invalid":"The payment ID is invalid. The length must be 16 or 64 characters" }, + "mixin":{ + "label":"Privacy" + }, "sendButton":"Send", "cancelButton":"Cancel" }, From 4c08ca8179c98c73aa7f46b183bb81e9a140222e Mon Sep 17 00:00:00 2001 From: aiwe Date: Tue, 15 Feb 2022 00:54:25 +0200 Subject: [PATCH 07/11] Fix mixin validation (not used yet) --- src/model/TransactionsExplorer.ts | 6 ++++-- src/pages/send.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/model/TransactionsExplorer.ts b/src/model/TransactionsExplorer.ts index 297bfa2e..733fb06e 100644 --- a/src/model/TransactionsExplorer.ts +++ b/src/model/TransactionsExplorer.ts @@ -598,12 +598,14 @@ export class TransactionsExplorer { amounts.push(usingOuts[l].amount); } - obtainMixOutsCallback(amounts, (mixin + 1)).then(function (lotsMixOuts: any[]) { + let nbOutsNeeded: number = mixin + 1; + + obtainMixOutsCallback(amounts, nbOutsNeeded).then(function (lotsMixOuts: any[]) { console.log('------------------------------mix_outs'); console.log('amounts', amounts); console.log('lots_mix_outs', lotsMixOuts); - TransactionsExplorer.createRawTx(dsts, wallet, false, usingOuts, pid_encrypt, /*mix_outs*/lotsMixOuts, mixin, neededFee, paymentId).then(function (data: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { + TransactionsExplorer.createRawTx(dsts, wallet, false, usingOuts, pid_encrypt, lotsMixOuts, mixin, neededFee, paymentId).then(function (data: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { resolve(data); }).catch(function (e) { reject(e); diff --git a/src/pages/send.ts b/src/pages/send.ts index f873cd08..3cdc2032 100644 --- a/src/pages/send.ts +++ b/src/pages/send.ts @@ -430,7 +430,7 @@ class SendView extends DestructableView { @VueWatched() mixinIsValid() { try { - if (this.mixIn > 10 || this.mixIn < 0 || this.mixIn === 1 || this.mixIn === 2) + if (this.mixIn > 10 || (this.mixIn < 3 && this.mixIn !== 0)) this.mixinIdValid = false; } catch (e) { From 2647323f071958abe626447b5628239f5f5b3263 Mon Sep 17 00:00:00 2001 From: aiwe Date: Tue, 15 Feb 2022 01:36:41 +0200 Subject: [PATCH 08/11] Fix sending with mixin, todo: mixin validation --- src/pages/send.html | 5 ++++- src/pages/send.ts | 21 ++++++++++++++------- src/translations/en.json | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/pages/send.html b/src/pages/send.html index 1f7560b8..0f6a992b 100644 --- a/src/pages/send.html +++ b/src/pages/send.html @@ -54,7 +54,10 @@

{{ $t("sendPage.qrCodeScanning.explication") }}

- + +
+ {{ $t("sendPage.sendBlock.mixin.invalid") }} +
diff --git a/src/pages/send.ts b/src/pages/send.ts index 3cdc2032..b7fc995b 100644 --- a/src/pages/send.ts +++ b/src/pages/send.ts @@ -42,8 +42,8 @@ class SendView extends DestructableView { @VueVar(true) amountToSendValid !: boolean; @VueVar('') paymentId !: string; @VueVar(true) paymentIdValid !: boolean; - @VueVar(3) mixIn !: number; - @VueVar(true) mixinIdValid !: boolean; + @VueVar('3') mixIn !: string; + @VueVar(true) mixinIsValid !: boolean; @VueVar(null) domainAliasAddress !: string | null; @VueVar(null) txDestinationName !: string | null; @@ -88,6 +88,7 @@ class SendView extends DestructableView { this.domainAliasAddress = null; this.txDestinationName = null; this.txDescription = null; + this.mixIn = config.defaultMixin.toString(); this.stopScan(); } @@ -246,6 +247,9 @@ class SendView extends DestructableView { swal.showLoading(); } }); + + let mixinToSendWith: number = parseInt(self.mixIn); + TransactionsExplorer.createTx([{address: destinationAddress, amount: amountToSend}], self.paymentId, wallet, blockchainHeight, function (amounts: number[], numberOuts: number): Promise { return blockchainExplorer.getRandomOuts(amounts, numberOuts); @@ -293,7 +297,7 @@ class SendView extends DestructableView { }, 1); }); }, - self.mixIn).then(function (rawTxData: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { + mixinToSendWith).then(function (rawTxData: { raw: { hash: string, prvkey: string, raw: string }, signed: any }) { blockchainExplorer.sendRawTx(rawTxData.raw.raw).then(function () { //save the tx private key wallet.addTxPrivateKeyWithTxHash(rawTxData.raw.hash, rawTxData.raw.prvkey); @@ -428,13 +432,16 @@ class SendView extends DestructableView { } @VueWatched() - mixinIsValid() { + mixinWatch() { try { - if (this.mixIn > 10 || (this.mixIn < 3 && this.mixIn !== 0)) - this.mixinIdValid = false; + this.mixinIsValid = !isNaN(parseFloat(this.mixIn)); + + let mixin: number = parseFloat(this.mixIn); + if (mixin > 10 || (mixin < 3 && mixin !== 0)) + this.mixinIsValid = false; } catch (e) { - this.mixinIdValid = false; + this.mixinIsValid = false; } } } diff --git a/src/translations/en.json b/src/translations/en.json index 167e0e56..b8b9c469 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -231,7 +231,8 @@ "invalid":"The payment ID is invalid. The length must be 16 or 64 characters" }, "mixin":{ - "label":"Privacy" + "label":"Privacy", + "invalid":"The mixin is invalid, should be from 3 to 10 or zero" }, "sendButton":"Send", "cancelButton":"Cancel" From 631cea2f9ddd0512c5199c304220caf74be4ea2f Mon Sep 17 00:00:00 2001 From: aiwe Date: Tue, 15 Feb 2022 11:33:26 +0200 Subject: [PATCH 09/11] Added basic automatic correction of mixin in send form --- src/pages/send.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/send.html b/src/pages/send.html index 0f6a992b..464e2fe8 100644 --- a/src/pages/send.html +++ b/src/pages/send.html @@ -54,7 +54,8 @@

{{ $t("sendPage.qrCodeScanning.explication") }}

- +
{{ $t("sendPage.sendBlock.mixin.invalid") }}
From 38c48459e70dc197616991f30d4b80548c0d2ec2 Mon Sep 17 00:00:00 2001 From: aiwe Date: Tue, 15 Feb 2022 13:43:05 +0200 Subject: [PATCH 10/11] I prefer the filed to be highlighted and have same height as others --- src/assets/css/main.css | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 9991f2a6..f3f6153f 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -903,7 +903,7 @@ body{ font-weight: 400; margin-bottom:5px; } -.field input, .field .subfield, .field select{ +.field input, .field select{ border: 1px solid #D9DCE7; border-radius: 5px; font-size: 14px; @@ -911,6 +911,11 @@ body{ width: 100%; color: rgba(71, 78, 93, 0.7); background: #FFFFFF; + position: relative; +} + +.field .subfield{ + position: relative; } .field input:read-only, .field input.readonly, .field .subfield.readonly{ @@ -925,21 +930,36 @@ body{ padding: 0; } .field .subfield input{ - width: calc(100% - 41px); + /*width: calc(100% - 41px); border:none; padding: 5px; + display: inline-block;*/ display: inline-block; + border: 1px solid #D9DCE7; + border-radius: 5px; + font-size: 14px; + padding: 17px 16px 15px; + width: 100%; + color: rgba(71, 78, 93, 0.7); + background: #FFFFFF; } .field .subfield input.twoActions { width: calc(100% - 82px); } .field .subfield .action{ - width: 20px; + /*width: 20px; border-left:1px solid #D9DCE7; padding: 18px 8px; display: inline-block; - height: 100%; + height: 100%;*/ + border-left: 1px solid #D9DCE7; + padding: 18px 8px; + display: block; + height: auto; + position: absolute; + top: 0; + right: 0; } .field.checkbox input{ From d69e92bd2956af0b9ec2e83e49bdd45fa94b742e Mon Sep 17 00:00:00 2001 From: aiwe Date: Tue, 15 Feb 2022 14:07:15 +0200 Subject: [PATCH 11/11] Add translations of mixin related strings --- src/translations/de.json | 4 ++++ src/translations/es.json | 4 ++++ src/translations/fa.json | 4 ++++ src/translations/fr.json | 4 ++++ src/translations/gr.json | 4 ++++ src/translations/hu.json | 4 ++++ src/translations/it.json | 4 ++++ src/translations/ko.json | 4 ++++ src/translations/pl.json | 4 ++++ src/translations/ru.json | 4 ++++ src/translations/sr.json | 6 +++++- src/translations/uk.json | 8 ++++++-- src/translations/zh.json | 4 ++++ 13 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/translations/de.json b/src/translations/de.json index df02e32f..8c68a13d 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -229,6 +229,10 @@ "label":"Payment ID (optional)", "invalid":"Die payment ID ist ungültig. Sie muss aus 16 oder 64 Zeichen bestehen" }, + "mixin":{ + "label":"Geheimhaltung", + "invalid":"Das Mixin ist ungültig, sollte zwischen 3 und 10 oder null liegen" + }, "sendButton":"Senden", "cancelButton":"Abbrechen" }, diff --git a/src/translations/es.json b/src/translations/es.json index cdc5e66c..cbd5f8f7 100644 --- a/src/translations/es.json +++ b/src/translations/es.json @@ -231,6 +231,10 @@ "label": "Identificación de pago (opcional)", "invalid": "El ID de pago no es válido. La longitud debe ser de 16 o 64 caracteres." }, + "mixin":{ + "label":"Intimidad", + "invalid":"El mixin no es válido, debe ser de 3 a 10 o cero" + }, "sendButton": "Enviar", "cancelButton": "Cancelar" }, diff --git a/src/translations/fa.json b/src/translations/fa.json index e92fe24e..c685414c 100644 --- a/src/translations/fa.json +++ b/src/translations/fa.json @@ -227,6 +227,10 @@ "label": "شناسه واریز", "invalid": "شناسه ی واریز اشتباه است مقداری را بین شانزده تا شصت و چهار کاراکتر وارد نمایید" }, + "mixin":{ + "label":"حریم خصوصی", + "invalid":"میکسین نامعتبر است، باید از 3 تا 10 یا صفر باشد" + }, "sendButton": "ارسال", "cancelButton": "لغو" }, diff --git a/src/translations/fr.json b/src/translations/fr.json index 67c22edc..32cea41b 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -229,6 +229,10 @@ "label":"Identifiant du payment (optionnel)", "invalid":"L'identifiant du paiement est invalid. La longeur doit être de 16 ou 64 caractères" }, + "mixin":{ + "label":"Confidentialité", + "invalid":"Le mixin est invalide, doit être compris entre 3 et 10 ou zéro" + }, "sendButton":"Envoyer", "cancelButton":"Annuler" }, diff --git a/src/translations/gr.json b/src/translations/gr.json index 57d669e6..1c2e8975 100644 --- a/src/translations/gr.json +++ b/src/translations/gr.json @@ -229,6 +229,10 @@ "label":"Payment ID (προαιρετικό)", "invalid":"Το payment ID είναι άκυρο. Πρέπει να αποτελείται από 16 ή 64 χαρακτήρες" }, + "mixin":{ + "label":"Μυστικότητα", + "invalid":"Το mixin δεν είναι έγκυρο, θα πρέπει να είναι από 3 έως 10 ή μηδέν" + }, "sendButton":"Αποστολή", "cancelButton":"Ακύρωση" }, diff --git a/src/translations/hu.json b/src/translations/hu.json index dfbda7de..2b85a8c4 100644 --- a/src/translations/hu.json +++ b/src/translations/hu.json @@ -229,6 +229,10 @@ "label":"Fizetési azonosító (opcionális)", "invalid":"Érvénytelen fizetési azonosító. Hosszának 16 vagy 64 karakternek kell lennie" }, + "mixin":{ + "label":"Magánélet", + "invalid":"A mixin érvénytelen, 3 és 10 között vagy nulla lehet" + }, "sendButton":"Küldés", "cancelButton":"Mégsem" }, diff --git a/src/translations/it.json b/src/translations/it.json index 6ef87ae3..bc854691 100644 --- a/src/translations/it.json +++ b/src/translations/it.json @@ -228,6 +228,10 @@ "label":"Payment ID (opzionale)", "invalid":"Il Payment ID è invalido. La lunghezza deve essere di 16 o 64 caratteri" }, + "mixin":{ + "label":"Riservatezza", + "invalid":"Il mixin non è valido, dovrebbe essere compreso tra 3 e 10 o zero" + }, "sendButton":"Invia", "cancelButton":"Annulla" }, diff --git a/src/translations/ko.json b/src/translations/ko.json index 5b708327..a8a1f276 100644 --- a/src/translations/ko.json +++ b/src/translations/ko.json @@ -232,6 +232,10 @@ "label": "페이먼트 ID (옵션)", "invalid": "페이먼트 ID가 올바르지 않습니다. 올바른 ID의 문자길이는 16 또는 64 문자입니다." }, + "mixin":{ + "label":"은둔", + "invalid":"믹스인이 잘못되었습니다. 3에서 10 또는 0이어야 합니다." + }, "sendButton": "보내기", "cancelButton": "취소" }, diff --git a/src/translations/pl.json b/src/translations/pl.json index e3d0b73b..5a3de5d4 100644 --- a/src/translations/pl.json +++ b/src/translations/pl.json @@ -228,6 +228,10 @@ "label":"Identyfikator płatności (opcjonalnie)", "invalid":"Identyfikator płatności jest nieprawidłowy. Długość musi wynosić 64 znaki" }, + "mixin":{ + "label":"Poufność", + "invalid":"Mieszanka jest nieprawidłowa, powinna wynosić od 3 do 10 lub zero" + }, "sendButton":"Wyślij", "cancelButton":"Przerwij" }, diff --git a/src/translations/ru.json b/src/translations/ru.json index 74ec2ef3..670f5d07 100644 --- a/src/translations/ru.json +++ b/src/translations/ru.json @@ -230,6 +230,10 @@ "label":"Payment ID (необязательно)", "invalid":"Идентификатор платежа неверный. Длина должна быть 16 или 64 символа" }, + "mixin":{ + "label":"Конфиденциальность", + "invalid":"Миксин неправильный, должен быть от 3 до 10 или нуль" + }, "sendButton":"Отправить", "cancelButton":"Отменить" }, diff --git a/src/translations/sr.json b/src/translations/sr.json index 902b6680..08fc32a8 100644 --- a/src/translations/sr.json +++ b/src/translations/sr.json @@ -227,9 +227,13 @@ "invalid":"Количина неисправна" }, "paymentId":{ - "label":"ID уплате(произвољан корак)", + "label":"ID уплате (произвољан корак)", "invalid":"ID уплате неисправан. Дужина мора бити између 16 и 64 карактера" }, + "mixin":{ + "label":"Приватност", + "invalid":"Миксин је неважећи, требало би да буде од 3 до 10 или нула" + }, "sendButton":"Пошаљи", "cancelButton":"Откажи" }, diff --git a/src/translations/uk.json b/src/translations/uk.json index 700481b9..31122192 100644 --- a/src/translations/uk.json +++ b/src/translations/uk.json @@ -230,11 +230,15 @@ "label":"Payment ID (не обов'язково)", "invalid":"Ідентифікатор платежу невірний. Довжина повинна бути 16 або 64 символи" }, + "mixin":{ + "label":"Конфіденційність", + "invalid":"Міксін неправильный, має бути від 3 до 10 або нуль" + }, "sendButton":"Надіслати", "cancelButton":"Скасувати" }, "qrCodeScanning":{ - "explication":"Показати QR код" + "explication":"Сканувати QR код" }, "notEnoughMoneyModal":{ "title":"Ой...", @@ -395,7 +399,7 @@ "importButton":"Імпортувати" }, "qrScanningBlock":{ - "title":"Покажіть QR код" + "title":"Наведіть на QR код" } }, "exportPage":{ diff --git a/src/translations/zh.json b/src/translations/zh.json index d9c7259d..a2f11c9a 100644 --- a/src/translations/zh.json +++ b/src/translations/zh.json @@ -232,6 +232,10 @@ "label": "付款ID(可选)", "invalid": "非法的付款ID. 长度必须是64位。" }, + "mixin":{ + "label":"隐私", + "invalid":"mixin 无效,应为 3 到 10 或零" + }, "sendButton": "发送", "cancelButton": "取消" },