Skip to content

Commit

Permalink
TX : fix #94 allow to mix inputs/outputs with different base
Browse files Browse the repository at this point in the history
  • Loading branch information
blavenie committed Aug 26, 2016
1 parent 2b3a933 commit c7e7d4f
Showing 1 changed file with 59 additions and 56 deletions.
115 changes: 59 additions & 56 deletions www/js/services/wallet-services.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,12 +608,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
finishLoadRequirements();
}));
}
// Get sources
if (options.source) {
if (options.sources || options.tx) {
// Get sources
jobs.push(loadSources());
}
// Get transactions
if (options.tx) {
// Get transactions
jobs.push(loadTransactions());
}
// API extension
Expand Down Expand Up @@ -641,39 +639,39 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
return lastDigits === 0; // no rest
},

getInputs = function(amount, filterBase, outputBase, offset) {
if (!outputBase) {
outputBase = filterBase;
truncBase = function(amount, base) {
var pow = Math.pow(10, base);
return Math.trunc(amount / pow ) * pow;
},

getInputs = function(amount, outputBase, filterBase) {
if (angular.isUndefined(filterBase)) {
filterBase = outputBase;
}
var sourcesAmount = 0;
var sources = [];
var minBase = filterBase;
var maxBase = filterBase;
var i = 0;
_.forEach(data.sources, function(source) {
var skip = source.consumed || (source.base !== filterBase) || (offset && i++ < offset);
var skip = source.consumed || (source.base !== filterBase);
if (!skip){
sourcesAmount += (source.base > 0) ? (source.amount * Math.pow(10, source.base)) : source.amount;
sources.push(source);
// Stop if excat amount OR compatible with base
if (sourcesAmount === amount ||
(sourcesAmount > amount && isBase(sourcesAmount, outputBase))) {
// Stop if enough sources
if (sourcesAmount >= amount) {
return false;
}
}
});

while (sourcesAmount < amount && filterBase > 0) {
// IF not enough sources, get add inputs from lower base (recursively)
if (sourcesAmount < amount && filterBase > 0) {
filterBase -= 1;
var missingAmount = amount - sourcesAmount;
var lowerInputs = getInputs(missingAmount, filterBase, outputBase);
// Try to get a rounded amount, regarding expected base
var lowerOffset = 1;
while (lowerInputs.amount > 0 && !isBase(lowerInputs.amount, outputBase)) {
lowerOffset += 1;
lowerInputs = getInputs(missingAmount, filterBase, outputBase, lowerOffset);
}
var lowerInputs = getInputs(missingAmount, outputBase, filterBase);

// Add lower base inputs to result
if (lowerInputs.amount > 0) {
minBase = lowerInputs.minBase;
sourcesAmount += lowerInputs.amount;
Expand Down Expand Up @@ -711,50 +709,48 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
if (amount <= 0) {
reject({message:'ERROR.AMOUNT_NEGATIVE'}); return;
}
amount = Math.floor(amount); // remove decimals

var inputs= {
var inputs = {
amount: 0,
minBase: block.unitbase,
maxBase: block.unitbase + 1,
intputs: []
sources : []
};
var amountBase = 0;
while (inputs.amount < amount && amountBase <= block.unitbase) {

// Round amount to current base
var basePow = block.unitbase ? Math.pow(10, block.unitbase) : 1;
if (amount > basePow) {
amount = Math.floor(amount / basePow) * basePow;
}
else {
inputs.maxBase = (''+amount).length;
}
if (amount > data.balance) {
reject({message:'ERROR.NOT_ENOUGH_CREDIT'}); return;
}
// Get inputs, starting to use current base sources
inputs = getInputs(amount, block.unitbase);

var maxAmount = 0;
while (inputs.amount < amount && inputs.maxBase > 0) {
inputs = getInputs(amount, inputs.maxBase - 1);
maxAmount = (inputs.amount > maxAmount) ? inputs.amount : maxAmount;
// Reduce amount (remove last digits)
amountBase++;
if (inputs.amount < amount && amountBase <= block.unitbase) {
amount = truncBase(amount, amountBase);
}
}

if (inputs.amount < amount) {
if (inputs.amount === 0) {
reject({message:'ERROR.ALL_SOURCES_USED'});
if (data.balance < amount) {
reject({message:'ERROR.NOT_ENOUGH_CREDIT'}); return;
}
else if (inputs.amount === 0) {
reject({message:'ERROR.ALL_SOURCES_USED'}); return;
}
else {
$translate('COMMON.UD')
.then(function(UD) {
var params;
if(useRelative) {
params = {
amount: ($filter('formatDecimal')(maxAmount / data.currentUD)),
amount: ($filter('formatDecimal')(inputs.amount / data.currentUD)),
unit: UD,
subUnit: $filter('abbreviate')(data.currency)
};
}
else {
params = {
amount: ($filter('formatInteger')(maxAmount)),
amount: ($filter('formatInteger')(inputs.amount)),
unit: $filter('abbreviate')(data.currency),
subUnit: ''
};
Expand All @@ -767,6 +763,9 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
}
return;
}
if (amountBase > 0) {
console.debug("[wallet] Amount has been truncate to " + amount);
}

var tx = 'Version: 3\n' +
'Type: Transaction\n' +
Expand All @@ -791,23 +790,27 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser

tx += 'Outputs:\n';
// AMOUNT:BASE:CONDITIONS
if (inputs.maxBase > 0) { // add offset
tx += Math.floor(amount / Math.pow(10, inputs.maxBase));
}
else {
tx += amount;
}
tx += ':'+inputs.maxBase+':SIG('+destPub+')\n';

if (inputs.amount > amount) {
var rest = (inputs.amount-amount);
if (inputs.maxBase > 0) { // add offset
tx += Math.floor(rest / Math.pow(10, inputs.maxBase));
var rest = amount;
var outputBase = inputs.maxBase;
while(rest > 0) {
var outputAmount = truncBase(rest, outputBase);
rest -= outputAmount;
if (outputAmount > 0) {
outputAmount = outputBase === 0 ? outputAmount : outputAmount / Math.pow(10, outputBase);
tx += outputAmount + ':' + outputBase + ':SIG(' + destPub + ')\n'
}
else {
tx += rest;
outputBase--;
}
rest = inputs.amount - amount;
outputBase = inputs.maxBase;
while(rest > 0) {
var outputAmount = truncBase(rest, outputBase);
rest -= outputAmount;
if (outputAmount > 0) {
outputAmount = outputBase === 0 ? outputAmount : outputAmount / Math.pow(10, outputBase);
tx += outputAmount +':'+outputBase+':SIG('+data.pubkey+')\n'
}
tx += ':'+inputs.maxBase+':SIG('+data.pubkey+')\n';
outputBase--;
}

tx += "Comment: "+ (!!comments?comments:"") + "\n";
Expand Down

0 comments on commit c7e7d4f

Please sign in to comment.