fix inadvertent double spending with coin selection

This commit is contained in:
Florian Dold 2016-03-05 01:36:38 +01:00
parent 1b2897c03b
commit 8cbef4c4c7
4 changed files with 44 additions and 61 deletions

View File

@ -35,34 +35,16 @@ var TalerNotify;
return url;
}
var handlers = [];
var connected = false;
// Hack to know when the extension is unloaded
var port;
var connect = function (dh) {
port = chrome.runtime.connect();
port.onDisconnect.addListener(dh);
chrome.runtime.sendMessage({ type: "ping" }, function () {
console.log("registering handlers");
connected = true;
registerHandlers();
});
};
var disconectHandler = function () {
if (connected) {
console.log("chrome runtime disconnected, removing handlers");
for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {
var handler = handlers_1[_i];
document.removeEventListener(handler.type, handler.listener);
}
var port = chrome.runtime.connect();
port.onDisconnect.addListener(function () {
console.log("chrome runtime disconnected, removing handlers");
for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {
var handler = handlers_1[_i];
document.removeEventListener(handler.type, handler.listener);
}
else {
// We got disconnected before the extension was ready, reconnect ...
window.setTimeout(function () {
connect(disconectHandler);
}, 200);
}
};
connect(disconectHandler);
});
registerHandlers();
function registerHandlers() {
var $ = function (x) { return document.getElementById(x); };
function addHandler(type, listener) {

View File

@ -45,36 +45,17 @@ namespace TalerNotify {
const handlers = [];
let connected = false;
// Hack to know when the extension is unloaded
let port;
let port = chrome.runtime.connect();
const connect = (dh) => {
port = chrome.runtime.connect();
port.onDisconnect.addListener(dh);
chrome.runtime.sendMessage({type: "ping"}, () => {
console.log("registering handlers");
connected = true;
registerHandlers();
});
};
var disconectHandler = () => {
if (connected) {
console.log("chrome runtime disconnected, removing handlers");
for (let handler of handlers) {
document.removeEventListener(handler.type, handler.listener);
}
} else {
// We got disconnected before the extension was ready, reconnect ...
window.setTimeout(() => {
connect(disconectHandler);
}, 200);
port.onDisconnect.addListener(() => {
console.log("chrome runtime disconnected, removing handlers");
for (let handler of handlers) {
document.removeEventListener(handler.type, handler.listener);
}
};
});
connect(disconectHandler);
registerHandlers();
function registerHandlers() {
const $ = (x) => document.getElementById(x);

View File

@ -144,6 +144,7 @@ class QueryStreamIndexJoin<T> extends QueryStreamBase<T> {
f(true, undefined, tx);
return;
}
console.log("joining on", this.key(value));
let s = tx.objectStore(this.storeName).index(this.indexName);
let req = s.openCursor(IDBKeyRange.only(this.key(value)));
req.onsuccess = () => {
@ -163,14 +164,14 @@ class QueryStreamIndexJoin<T> extends QueryStreamBase<T> {
class IterQueryStream<T> extends QueryStreamBase<T> {
private storeName;
private options;
private subscribers;
constructor(qr, storeName, options) {
super(qr);
this.options = options;
this.storeName = storeName;
}
this.subscribers = [];
subscribe(f) {
let doIt = (tx) => {
const {indexName = void 0, only = void 0} = this.options;
let s;
@ -188,16 +189,24 @@ class IterQueryStream<T> extends QueryStreamBase<T> {
req.onsuccess = (e) => {
let cursor: IDBCursorWithValue = req.result;
if (cursor) {
f(false, cursor.value, tx);
for (let f of this.subscribers) {
f(false, cursor.value, tx);
}
cursor.continue();
} else {
f(true, undefined, tx);
for (let f of this.subscribers) {
f(true, undefined, tx);
}
}
}
};
this.root.addWork(doIt, null, false);
}
subscribe(f) {
this.subscribers.push(f);
}
}

View File

@ -352,8 +352,9 @@ export class Wallet {
// denomination
let m: ExchangeCoins = {};
function storeExchangeCoin(mc) {
function storeExchangeCoin(mc, url) {
let exchange: IExchangeInfo = mc[0];
console.log("got coin for exchange", url);
let coin: Coin = mc[1];
let cd = {
coin: coin,
@ -366,20 +367,28 @@ export class Wallet {
console.warn("same pubkey for different currencies");
return;
}
let x = m[exchange.baseUrl];
let x = m[url];
if (!x) {
m[exchange.baseUrl] = [cd];
m[url] = [cd];
} else {
x.push(cd);
}
}
let ps = allowedExchanges.map((info) => {
// Make sure that we don't look up coins
// for the same URL twice ...
let handledExchanges = new Set();
let ps = allowedExchanges.map((info: ExchangeHandle) => {
if (handledExchanges.has(info.url)) {
return;
}
handledExchanges.add(info.url);
console.log("Checking for merchant's exchange", JSON.stringify(info));
return Query(this.db)
.iter("exchanges", {indexName: "pubKey", only: info.master_pub})
.indexJoin("coins", "exchangeBaseUrl", (exchange) => exchange.baseUrl)
.reduce(storeExchangeCoin);
.reduce((x) => storeExchangeCoin(x, info.url));
});
return Promise.all(ps).then(() => {
@ -398,6 +407,8 @@ export class Wallet {
nextExchange:
for (let key in m) {
let coins = m[key];
console.log("trying coins");
console.log(coins);
// Sort by ascending deposit fee
coins.sort((o1, o2) => Amounts.cmp(o1.denom.fee_deposit,
o2.denom.fee_deposit));