Skip to content
Snippets Groups Projects
Commit 74d9f4d9 authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

- TX : fix #120 TX must not create output base lower than input

 - Account wizard : logout if failed - fix #98
parent b29806f0
No related branches found
No related tags found
No related merge requests found
...@@ -114,8 +114,16 @@ function NewAccountModalController($scope, $state, UIUtils, CryptoUtils, Wallet, ...@@ -114,8 +114,16 @@ function NewAccountModalController($scope, $state, UIUtils, CryptoUtils, Wallet,
return; return;
} }
var onErrorLogout = function(message) {
return function(err) {
Wallet.logout()
.then(function(){
UIUtils.onError(message)(err);
});
}
}
UIUtils.loading.show(); UIUtils.loading.show();
$scope.closeModal();
Wallet.login($scope.formData.username, $scope.formData.password) Wallet.login($scope.formData.username, $scope.formData.password)
.then(function() { .then(function() {
...@@ -131,12 +139,15 @@ function NewAccountModalController($scope, $state, UIUtils, CryptoUtils, Wallet, ...@@ -131,12 +139,15 @@ function NewAccountModalController($scope, $state, UIUtils, CryptoUtils, Wallet,
// Send membership IN // Send membership IN
Wallet.membership.inside() Wallet.membership.inside()
.then(function() { .then(function() {
$scope.closeModal();
// Redirect to wallet // Redirect to wallet
$state.go('app.view_wallet'); $state.go('app.view_wallet');
}) })
.catch(UIUtils.onError('ERROR.SEND_MEMBERSHIP_IN_FAILED')); .catch(onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED'));
}) })
.catch(UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')); .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED'));
}) })
.catch(function(err) { .catch(function(err) {
UIUtils.loading.hide(); UIUtils.loading.hide();
......
...@@ -135,58 +135,6 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -135,58 +135,6 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
$scope.registerForm = registerForm; $scope.registerForm = registerForm;
}; };
$scope.checkUidNotExists = function(uid, pubkey) {
return $q(function(resolve, reject) {
BMA.wot.lookup({ search: uid }) // search on uid
.then(function(res) {
var found = res.results &&
res.results.length > 0 &&
res.results.some(function(pub){
return pub.uids && pub.uids.length > 0 &&
pub.uids.some(function(idty) {
return ((idty.uid === uid) && // check Uid
(pub.pubkey !== pubkey || !idty.revoked)); // check pubkey
});
});
if (found) { // uid is already used : display a message and call failed callback
reject('ACCOUNT.NEW.MSG_UID_ALREADY_USED');
}
else {
resolve(uid);
}
})
.catch(function() {
resolve(uid);
});
});
};
$scope.checkPubkeyNotExists = function(uid, pubkey) {
return $q(function(resolve, reject) {
BMA.wot.lookup({ search: pubkey }) // search on pubkey
.then(function(res) {
var found = res.results &&
res.results.length > 0 &&
res.results.some(function(pub){
return pub.pubkey === pubkey &&
pub.uids && pub.uids.length > 0 &&
pub.uids.some(function(idty) {
return (!idty.revoked); // excluded revoked uid
});
});
if (found) { // uid is already used : display a message and reopen the popup
reject('ACCOUNT.NEW.MSG_PUBKEY_ALREADY_USED');
}
else {
resolve(uid);
}
})
.catch(function() {
resolve(uid);
});
});
};
// Ask uid // Ask uid
$scope.showUidPopup = function() { $scope.showUidPopup = function() {
return $q(function(resolve, reject) { return $q(function(resolve, reject) {
...@@ -231,16 +179,20 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -231,16 +179,20 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
// Send self identity // Send self identity
$scope.self= function() { $scope.self= function() {
if ($scope.actionsPopover) {
$scope.actionsPopover.hide();
}
$scope.showUidPopup() $scope.showUidPopup()
.then(function(uid) { .then(function(uid) {
UIUtils.loading.show(); UIUtils.loading.show();
Wallet.self(uid) Wallet.self(uid)
.then(function() { .then(function() {
$scope.doUpdate(); $scope.updateView();
UIUtils.loading.hide();
}) })
.catch(function(err){ .catch(function(err){
UIUtils.loading.hide();
UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')(err) UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')(err)
.then(function() { .then(function() {
$scope.self(); // loop $scope.self(); // loop
...@@ -251,8 +203,16 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -251,8 +203,16 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
// Send membership IN // Send membership IN
$scope.membershipIn= function() { $scope.membershipIn= function() {
if ($scope.actionsPopover) {
$scope.actionsPopover.hide();
}
var doMembershipIn = function(retryCount) { var doMembershipIn = function(retryCount) {
Wallet.membership.inside() Wallet.membership.inside()
.then(function() {
$scope.updateView();
UIUtils.loading.hide();
})
.catch(function(err) { .catch(function(err) {
if (!retryCount || retryCount <= 2) { if (!retryCount || retryCount <= 2) {
$timeout(function() { $timeout(function() {
...@@ -260,7 +220,10 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -260,7 +220,10 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
}, 1000); }, 1000);
} }
else { else {
UIUtils.onError('ERROR.SEND_MEMBERSHIP_IN_FAILED')(err); UIUtils.onError('ERROR.SEND_MEMBERSHIP_IN_FAILED')(err)
.then(function() {
$scope.membershipIn(); // loop
});
} }
}); });
}; };
...@@ -276,7 +239,12 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -276,7 +239,12 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
.then(function() { .then(function() {
doMembershipIn(); doMembershipIn();
}) })
.catch(UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')); .catch(function(err){
UIUtils.onError('ERROR.SEND_IDENTITY_FAILED')(err)
.then(function() {
$scope.membershipIn(); // loop
});
});
} }
else { else {
doMembershipIn(); doMembershipIn();
...@@ -292,6 +260,11 @@ function WalletController($scope, $q, $ionicPopup, $timeout, ...@@ -292,6 +260,11 @@ function WalletController($scope, $q, $ionicPopup, $timeout,
// Send membership IN // Send membership IN
$scope.membershipOut = function() { $scope.membershipOut = function() {
if ($scope.actionsPopover) {
$scope.actionsPopover.hide();
}
// TODO Add confirmation message
UIUtils.loading.show(); UIUtils.loading.show();
Wallet.membership.out() Wallet.membership.out()
.catch(UIUtils.onError('ERROR.SEND_MEMBERSHIP_OUT_FAILED')); .catch(UIUtils.onError('ERROR.SEND_MEMBERSHIP_OUT_FAILED'));
......
...@@ -717,18 +717,20 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser ...@@ -717,18 +717,20 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
maxBase: block.unitbase + 1, maxBase: block.unitbase + 1,
sources : [] sources : []
}; };
var amountBase = 0;
while (inputs.amount < amount && amountBase <= block.unitbase) {
// Get inputs, starting to use current base sources // Get inputs, starting to use current base sources
var amountBase = 0;
while (inputs.amount < amount && amountBase <= block.unitbase) {
inputs = getInputs(amount, block.unitbase); inputs = getInputs(amount, block.unitbase);
// Reduce amount (remove last digits) if (inputs.amount < amount) {
// try to reduce amount (replace last digits to zero)
amountBase++; amountBase++;
if (inputs.amount < amount && amountBase <= block.unitbase) { if (amountBase <= block.unitbase) {
amount = truncBase(amount, amountBase); amount = truncBase(amount, amountBase);
} }
} }
}
if (inputs.amount < amount) { if (inputs.amount < amount) {
if (data.balance < amount) { if (data.balance < amount) {
...@@ -763,9 +765,15 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser ...@@ -763,9 +765,15 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
} }
return; return;
} }
if (amountBase > 0) { // Avoid to get outputs on lower base
if (amountBase < inputs.minBase && !isBase(amount, inputs.minBase)) {
amount = truncBase(amount, inputs.minBase);
console.debug("[wallet] Amount has been truncate to " + amount); console.debug("[wallet] Amount has been truncate to " + amount);
} }
else if (amountBase > 0) {
console.debug("[wallet] Amount has been truncate to " + amount);
}
var tx = 'Version: 3\n' + var tx = 'Version: 3\n' +
'Type: Transaction\n' + 'Type: Transaction\n' +
...@@ -852,35 +860,101 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser ...@@ -852,35 +860,101 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
}); });
}, },
checkUidNotExists = function(uid, pubkey) {
return $q(function(resolve, reject) {
BMA.wot.lookup({ search: uid }) // search on uid
.then(function(res) {
var found = res.results &&
res.results.length > 0 &&
res.results.some(function(pub){
return pub.uids && pub.uids.length > 0 &&
pub.uids.some(function(idty) {
return ((idty.uid === uid) && // check Uid
(pub.pubkey !== pubkey || !idty.revoked)); // check pubkey
});
});
if (found) { // uid is already used : display a message and call failed callback
reject({message: 'ACCOUNT.NEW.MSG_UID_ALREADY_USED'});
}
else {
resolve(uid);
}
})
.catch(function() {
resolve(uid); // not found, so OK
});
});
},
checkPubkeyNotExists = function(uid, pubkey) {
return $q(function(resolve, reject) {
BMA.wot.lookup({ search: pubkey }) // search on pubkey
.then(function(res) {
var found = res.results &&
res.results.length > 0 &&
res.results.some(function(pub){
return pub.pubkey === pubkey &&
pub.uids && pub.uids.length > 0 &&
pub.uids.some(function(idty) {
return (!idty.revoked); // excluded revoked uid
});
});
if (found) { // uid is already used : display a message and reopen the popup
reject('ACCOUNT.NEW.MSG_PUBKEY_ALREADY_USED');
}
else {
resolve(uid);
}
})
.catch(function() {
resolve(uid); // not found, so OK
});
});
},
/** /**
* Send self identity * Send self identity
*/ */
self = function(uid, requirements) { self = function(uid, needToLoadRequirements) {
return $q(function(resolve, reject) { return $q(function(resolve, reject) {
if (!BMA.regex.USER_ID.test(uid)){ if (!BMA.regex.USER_ID.test(uid)){
reject({message:'ERROR.INVALID_USER_ID'}); return; reject({message:'ERROR.INVALID_USER_ID'}); return;
} }
loadParameters() var block;
.then(function() { var identity;
$q.all([
// check uid used by another pubkey
checkUidNotExists(uid, data.pubkey),
// Load parameters (need to known the currency)
loadParameters(),
// Get th current block
BMA.blockchain.current() BMA.blockchain.current()
.then(function (block) { .then(function(current) {
// Create identity to sign block = current;
var identity = 'Version: 2\n' + })
])
// Create identity document to sign
.then(function() {
identity = 'Version: 2\n' +
'Type: Identity\n' + 'Type: Identity\n' +
'Currency: ' + data.currency + '\n' + 'Currency: ' + data.currency + '\n' +
'Issuer: ' + data.pubkey + '\n' + 'Issuer: ' + data.pubkey + '\n' +
'UniqueID: ' + uid + '\n' + 'UniqueID: ' + uid + '\n' +
'Timestamp: ' + block.number + '-' + block.hash + '\n'; 'Timestamp: ' + block.number + '-' + block.hash + '\n';
CryptoUtils.sign(identity, data.keypair) return CryptoUtils.sign(identity, data.keypair);
})
// Add signature
.then(function (signature) { .then(function (signature) {
var signedIdentity = identity + signature + '\n'; var signedIdentity = identity + signature + '\n';
// Send signed identity // Send to node
BMA.wot.add({identity: signedIdentity}) return BMA.wot.add({identity: signedIdentity})
.then(function (result) { .then(function (result) {
if (!!requirements) { if (!!needToLoadRequirements) {
// Refresh membership data // Refresh membership data (if need)
loadRequirements() loadRequirements()
.then(function () { .then(function () {
resolve(); resolve();
...@@ -904,12 +978,6 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser ...@@ -904,12 +978,6 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
}).catch(function (err) { }).catch(function (err) {
reject(err); reject(err);
}); });
}).catch(function (err) {
reject(err);
});
}).catch(function (err) {
reject(err);
});
}); });
}, },
...@@ -944,7 +1012,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser ...@@ -944,7 +1012,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
resolve(); resolve();
}) })
.catch(function(err){reject(err);}); .catch(function(err){reject(err);});
}, 200); }, 1000); // waiting for node to process membership doc
}).catch(function(err){reject(err);}); }).catch(function(err){reject(err);});
}).catch(function(err){reject(err);}); }).catch(function(err){reject(err);});
}).catch(function(err){reject(err);}); }).catch(function(err){reject(err);});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment