-
Notifications
You must be signed in to change notification settings - Fork 94
/
private_payment.js
95 lines (88 loc) · 3.57 KB
/
private_payment.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*jslint node: true */
"use strict";
var _ = require('lodash');
var storage = require('./storage.js');
var db = require('./db.js');
var conf = require('./conf.js');
var ValidationUtils = require("./validation_utils.js");
var indivisibleAsset = require('./indivisible_asset.js');
var divisibleAsset = require('./divisible_asset.js');
function findUnfinishedPastUnitsOfPrivateChains(arrChains, includeLatestElement, handleUnits){
var assocUnits = {};
arrChains.forEach(function(arrPrivateElements){
assocUnits[arrPrivateElements[0].payload.asset] = true; // require asset definition
for (var i = includeLatestElement ? 0 : 1; i<arrPrivateElements.length; i++) // skip latest element
assocUnits[arrPrivateElements[i].unit] = true;
});
var arrUnits = Object.keys(assocUnits);
storage.filterNewOrUnstableUnits(arrUnits, handleUnits);
}
function validateAndSavePrivatePaymentChain(arrPrivateElements, callbacks){
if (!ValidationUtils.isNonemptyArray(arrPrivateElements))
return callbacks.ifError("no priv elements array");
var headElement = arrPrivateElements[0];
if (!headElement.payload)
return callbacks.ifError("no payload in head element");
var asset = headElement.payload.asset;
if (!asset)
return callbacks.ifError("no asset in head element");
if (!ValidationUtils.isNonnegativeInteger(headElement.message_index))
return callbacks.ifError("no message index in head private element");
var validateAndSave = function(){
storage.readAsset(db, asset, null, function(err, objAsset){
if (err)
return callbacks.ifError(err);
if (!!objAsset.fixed_denominations !== !!headElement.payload.denomination)
return callbacks.ifError("presence of denomination field doesn't match the asset type");
db.takeConnectionFromPool(function(conn){
conn.query("BEGIN", function(){
var transaction_callbacks = {
ifError: function(err){
conn.query("ROLLBACK", function(){
conn.release();
callbacks.ifError(err);
});
},
ifOk: function(){
conn.query("COMMIT", function(){
conn.release();
callbacks.ifOk();
});
}
};
// check if duplicate
var sql = "SELECT address FROM outputs WHERE unit=? AND message_index=?";
var params = [headElement.unit, headElement.message_index];
if (objAsset.fixed_denominations){
if (!ValidationUtils.isNonnegativeInteger(headElement.output_index))
return transaction_callbacks.ifError("no output index in head private element");
sql += " AND output_index=?";
params.push(headElement.output_index);
}
conn.query(
sql,
params,
function(rows){
if (rows.length > 1)
throw Error("more than one output "+sql+' '+params.join(', '));
if (rows.length > 0 && rows[0].address){ // we could have this output already but the address is still hidden
console.log("duplicate private payment "+params.join(', '));
return transaction_callbacks.ifOk();
}
var assetModule = objAsset.fixed_denominations ? indivisibleAsset : divisibleAsset;
assetModule.validateAndSavePrivatePaymentChain(conn, arrPrivateElements, transaction_callbacks);
}
);
});
});
});
};
if (conf.bLight)
findUnfinishedPastUnitsOfPrivateChains([arrPrivateElements], false, function(arrUnfinishedUnits){
(arrUnfinishedUnits.length > 0) ? callbacks.ifWaitingForChain() : validateAndSave();
});
else
validateAndSave();
}
exports.findUnfinishedPastUnitsOfPrivateChains = findUnfinishedPastUnitsOfPrivateChains;
exports.validateAndSavePrivatePaymentChain = validateAndSavePrivatePaymentChain;