Commit 0b6206bc authored by Eriksson Monteiro's avatar Eriksson Monteiro

update millix node

parent c3dbf4f3
...@@ -17,14 +17,14 @@ class _I3EoELuQCmqwvp8C extends Endpoint { ...@@ -17,14 +17,14 @@ class _I3EoELuQCmqwvp8C extends Endpoint {
* @param req (p0: transaction_id, p1: date_begin, p2: date_end, p3: * @param req (p0: transaction_id, p1: date_begin, p2: date_end, p3:
* address_key_identifier, p4: is_double_spend, p5: * address_key_identifier, p4: is_double_spend, p5:
* double_spend_date_begin, p6: double_spend_date_end, p7: * double_spend_date_begin, p6: double_spend_date_end, p7:
* output_transaction_id, p8: order_by="create_date desc", p9: * output_transaction_id, p8: output_position, p9:
* record_limit=1000, p10: shard_id * order_by="create_date desc", p10: record_limit=1000, p11: shard_id
* @param res * @param res
*/ */
handler(app, req, res) { handler(app, req, res) {
const orderBy = req.query.p8 || 'create_date desc'; const orderBy = req.query.p9 || 'create_date desc';
const limit = parseInt(req.query.p9) || 1000; const limit = parseInt(req.query.p10) || 1000;
const shardID = req.query.p10 || undefined; const shardID = req.query.p11 || undefined;
database.applyShards((dbShardID) => { database.applyShards((dbShardID) => {
const transactionRepository = database.getRepository('transaction', dbShardID); const transactionRepository = database.getRepository('transaction', dbShardID);
...@@ -40,6 +40,7 @@ class _I3EoELuQCmqwvp8C extends Endpoint { ...@@ -40,6 +40,7 @@ class _I3EoELuQCmqwvp8C extends Endpoint {
double_spend_date_begin : req.query.p5, double_spend_date_begin : req.query.p5,
double_spend_date_end : req.query.p6, double_spend_date_end : req.query.p6,
output_transaction_id : req.query.p7, output_transaction_id : req.query.p7,
output_position : req.query.p8,
'transaction_input.shard_id' : shardID 'transaction_input.shard_id' : shardID
}, orderBy, limit); }, orderBy, limit);
}, orderBy, limit, shardID) }, orderBy, limit, shardID)
......
...@@ -772,7 +772,7 @@ export const DATABASE_ENGINE = 'sqlite'; ...@@ -772,7 +772,7 @@ export const DATABASE_ENGINE = 'sqlite';
export const DATABASE_CONNECTION = {}; export const DATABASE_CONNECTION = {};
export const MILLIX_CIRCULATION = 9e15; export const MILLIX_CIRCULATION = 9e15;
export const NODE_MILLIX_BUILD_DATE = 1631097631; export const NODE_MILLIX_BUILD_DATE = 1631097631;
export const NODE_MILLIX_VERSION = '1.11.10-tangled'; export const NODE_MILLIX_VERSION = '1.11.11-tangled';
export const DATA_BASE_DIR_MAIN_NETWORK = './millix-tangled'; export const DATA_BASE_DIR_MAIN_NETWORK = './millix-tangled';
export const DATA_BASE_DIR_TEST_NETWORK = './millix-tangled'; export const DATA_BASE_DIR_TEST_NETWORK = './millix-tangled';
let DATA_BASE_DIR = MODE_TEST_NETWORK ? DATA_BASE_DIR_TEST_NETWORK : DATA_BASE_DIR_MAIN_NETWORK; let DATA_BASE_DIR = MODE_TEST_NETWORK ? DATA_BASE_DIR_TEST_NETWORK : DATA_BASE_DIR_MAIN_NETWORK;
...@@ -817,7 +817,7 @@ if (DATABASE_ENGINE === 'sqlite') { ...@@ -817,7 +817,7 @@ if (DATABASE_ENGINE === 'sqlite') {
DATABASE_CONNECTION.SCRIPT_INIT_MILLIX_JOB_ENGINE = './scripts/initialize-millix-job-engine-sqlite3.sql'; DATABASE_CONNECTION.SCRIPT_INIT_MILLIX_JOB_ENGINE = './scripts/initialize-millix-job-engine-sqlite3.sql';
DATABASE_CONNECTION.SCRIPT_MIGRATION_DIR = './scripts/migration'; DATABASE_CONNECTION.SCRIPT_MIGRATION_DIR = './scripts/migration';
DATABASE_CONNECTION.SCRIPT_MIGRATION_SHARD_DIR = './scripts/migration/shard'; DATABASE_CONNECTION.SCRIPT_MIGRATION_SHARD_DIR = './scripts/migration/shard';
DATABASE_CONNECTION.SCHEMA_VERSION = '16'; DATABASE_CONNECTION.SCHEMA_VERSION = '17';
} }
export default { export default {
......
This diff is collapsed.
...@@ -235,12 +235,12 @@ export class Database { ...@@ -235,12 +235,12 @@ export class Database {
} }
console.log('Database initialized'); console.log('Database initialized');
this.databaseMillix.run('PRAGMA journal_mode = MEMORY', () => this.databaseMillix.run('PRAGMA synchronous = OFF', () => resolve())); this.databaseMillix.run('PRAGMA journal_mode = WAL', () => this.databaseMillix.run('PRAGMA synchronous = NORMAL', () => resolve()));
}); });
}); });
} }
else { else {
this.databaseMillix.run('PRAGMA journal_mode = MEMORY', () => this.databaseMillix.run('PRAGMA synchronous = OFF', () => resolve())); this.databaseMillix.run('PRAGMA journal_mode = WAL', () => this.databaseMillix.run('PRAGMA synchronous = NORMAL', () => resolve()));
} }
}); });
......
...@@ -14,7 +14,7 @@ export default class Node { ...@@ -14,7 +14,7 @@ export default class Node {
} }
addNodeAttributeType(attributeType) { addNodeAttributeType(attributeType) {
return new Promise(resolve => { return new Promise((resolve, reject) => {
let nodeAttributeID = this.normalizationRepository.get(attributeType); let nodeAttributeID = this.normalizationRepository.get(attributeType);
if (!nodeAttributeID) { if (!nodeAttributeID) {
nodeAttributeID = Database.generateID(20); nodeAttributeID = Database.generateID(20);
...@@ -26,7 +26,11 @@ export default class Node { ...@@ -26,7 +26,11 @@ export default class Node {
], (err) => { ], (err) => {
if (err) { if (err) {
this.database.get('SELECT attribute_type_id FROM node_attribute_type WHERE attribute_type = ?', this.database.get('SELECT attribute_type_id FROM node_attribute_type WHERE attribute_type = ?',
[attributeType], (_, row) => { [attributeType], (err, row) => {
if (!row) {
console.log("[node] unexpected error ", err, "attribute ", attributeType, " value", row);
return reject(err);
}
resolve(row.attribute_type_id); resolve(row.attribute_type_id);
}); });
return; return;
......
...@@ -33,6 +33,18 @@ export default class Transaction { ...@@ -33,6 +33,18 @@ export default class Transaction {
return Math.round(expireDate.getTime() / 1000) >= transactionDate; return Math.round(expireDate.getTime() / 1000) >= transactionDate;
} }
getExpiredTransactions() {
return new Promise((resolve) => {
this.database.all(`select transaction_id, transaction_date
from 'transaction'
where transaction_date >
strftime('%s', 'now', '${-config.TRANSACTION_OUTPUT_REFRESH_OLDER_THAN} minutes')`,
(err, data) => {
return resolve(data || []);
});
});
}
getTransactionInputChain(transaction) { getTransactionInputChain(transaction) {
return new Promise(resolve => { return new Promise(resolve => {
const dfs = (inputList, inputChain, processedInputTransactionSet = new Set()) => { const dfs = (inputList, inputChain, processedInputTransactionSet = new Set()) => {
...@@ -131,7 +143,7 @@ export default class Transaction { ...@@ -131,7 +143,7 @@ export default class Transaction {
getWalletBalance(keyIdentifier, stable) { getWalletBalance(keyIdentifier, stable) {
return new Promise((resolve) => { return new Promise((resolve) => {
this.database.get('SELECT SUM(amount) as amount FROM transaction_output ' + this.database.get('SELECT COALESCE(SUM(AMOUNT), 0) as amount FROM transaction_output ' +
'INNER JOIN `transaction` ON `transaction`.transaction_id = transaction_output.transaction_id ' + 'INNER JOIN `transaction` ON `transaction`.transaction_id = transaction_output.transaction_id ' +
'WHERE transaction_output.address_key_identifier=? AND transaction_output.is_stable = ' + (stable ? 1 : 0) + 'WHERE transaction_output.address_key_identifier=? AND transaction_output.is_stable = ' + (stable ? 1 : 0) +
' AND is_spent = 0 AND is_double_spend = 0 AND `transaction`.status != 3', [keyIdentifier], ' AND is_spent = 0 AND is_double_spend = 0 AND `transaction`.status != 3', [keyIdentifier],
...@@ -143,7 +155,7 @@ export default class Transaction { ...@@ -143,7 +155,7 @@ export default class Transaction {
getAddressBalance(address, stable) { getAddressBalance(address, stable) {
return new Promise((resolve) => { return new Promise((resolve) => {
this.database.get('SELECT SUM(amount) as amount FROM transaction_output INNER JOIN `transaction` ON `transaction`.transaction_id = transaction_output.transaction_id ' + this.database.get('SELECT COALESCE(SUM(AMOUNT), 0) as amount FROM transaction_output INNER JOIN `transaction` ON `transaction`.transaction_id = transaction_output.transaction_id ' +
'WHERE address=? AND transaction_output.is_stable = ' + (stable ? 1 : 0) + ' AND is_spent = 0 AND is_double_spend = 0 AND `transaction`.status != 3', [address], 'WHERE address=? AND transaction_output.is_stable = ' + (stable ? 1 : 0) + ' AND is_spent = 0 AND is_double_spend = 0 AND `transaction`.status != 3', [address],
(err, row) => { (err, row) => {
resolve(row ? row.amount || 0 : 0); resolve(row ? row.amount || 0 : 0);
...@@ -157,7 +169,7 @@ export default class Transaction { ...@@ -157,7 +169,7 @@ export default class Transaction {
SELECT address_key_identifier, SELECT address_key_identifier,
SUM(${stable ? 'balance_stable' : 'balance_pending'}) as ${stable ? 'balance_stable' : 'balance_pending'} SUM(${stable ? 'balance_stable' : 'balance_pending'}) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM (SELECT address_key_identifier, FROM (SELECT address_key_identifier,
SUM(amount) as ${stable ? 'balance_stable' : 'balance_pending'} COALESCE(SUM(AMOUNT), 0) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM transaction_output FROM transaction_output
WHERE is_stable = ${stable ? 1 : 0} WHERE is_stable = ${stable ? 1 : 0}
AND is_double_spend = 0 AND is_double_spend = 0
...@@ -166,7 +178,7 @@ export default class Transaction { ...@@ -166,7 +178,7 @@ export default class Transaction {
GROUP BY address_key_identifier GROUP BY address_key_identifier
UNION ALL UNION ALL
SELECT address_key_identifier, SELECT address_key_identifier,
SUM(amount) as ${stable ? 'balance_stable' : 'balance_pending'} COALESCE(SUM(AMOUNT), 0) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM shard_zero.transaction_output FROM shard_zero.transaction_output
WHERE is_stable = ${stable ? 1 : 0} WHERE is_stable = ${stable ? 1 : 0}
AND is_double_spend = 0 AND is_double_spend = 0
...@@ -191,7 +203,7 @@ export default class Transaction { ...@@ -191,7 +203,7 @@ export default class Transaction {
SELECT address, SELECT address,
SUM(${stable ? 'balance_stable' : 'balance_pending'}) as ${stable ? 'balance_stable' : 'balance_pending'} SUM(${stable ? 'balance_stable' : 'balance_pending'}) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM (SELECT address, FROM (SELECT address,
SUM(amount) as ${stable ? 'balance_stable' : 'balance_pending'} COALESCE(SUM(AMOUNT), 0) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM transaction_output FROM transaction_output
WHERE is_stable = ${stable ? 1 : 0} WHERE is_stable = ${stable ? 1 : 0}
AND is_double_spend = 0 AND is_double_spend = 0
...@@ -200,7 +212,7 @@ export default class Transaction { ...@@ -200,7 +212,7 @@ export default class Transaction {
GROUP BY address GROUP BY address
UNION ALL UNION ALL
SELECT address, SELECT address,
SUM(amount) as ${stable ? 'balance_stable' : 'balance_pending'} COALESCE(SUM(AMOUNT), 0) as ${stable ? 'balance_stable' : 'balance_pending'}
FROM shard_zero.transaction_output FROM shard_zero.transaction_output
WHERE is_stable = ${stable ? 1 : 0} WHERE is_stable = ${stable ? 1 : 0}
AND is_double_spend = 0 AND is_double_spend = 0
...@@ -323,6 +335,56 @@ export default class Transaction { ...@@ -323,6 +335,56 @@ export default class Transaction {
}); });
} }
getTransactionToSyncWallet(addressKeyIdentifier) {
return new Promise((resolve, reject) => {
this.database.all(`select distinct transaction_id
from (select o.transaction_id
from shard_zero.transaction_output o
left join shard_zero.transaction_input i
on o.transaction_id =
i.output_transaction_id and
o.output_position =
i.output_position
where i.transaction_id is null
and o.address_key_identifier = ?1
union
select o.transaction_id
from transaction_output o
left join transaction_input i
on o.transaction_id =
i.output_transaction_id and
o.output_position =
i.output_position
where i.transaction_id is null
and o.address_key_identifier = ?1
union
select i.transaction_id
from transaction_input i
left join transaction_output o
on i.transaction_id =
o.transaction_id and
o.address_key_identifier =
?1
where o.transaction_id is NULL
and i.address_key_identifier = ?1
union
select i.transaction_id
from shard_zero.transaction_input i
left join shard_zero.transaction_output o
on i.transaction_id =
o.transaction_id and
o.address_key_identifier =
?1
where o.transaction_id is NULL
and i.address_key_identifier = ?1)`, [addressKeyIdentifier], (err, data) => {
if (err) {
return reject(err);
}
return resolve(data);
});
});
}
getTransactionByAddressKeyIdentifier(addressKeyIdentifier, returnValidTransactions = false) { getTransactionByAddressKeyIdentifier(addressKeyIdentifier, returnValidTransactions = false) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.database.all(`WITH transaction_wallet AS ( this.database.all(`WITH transaction_wallet AS (
...@@ -414,11 +476,11 @@ export default class Transaction { ...@@ -414,11 +476,11 @@ export default class Transaction {
WHERE transaction_output.address_key_identifier = ? AND transaction_output.status != 3 \ WHERE transaction_output.address_key_identifier = ? AND transaction_output.status != 3 \
), \ ), \
transaction_amount AS ( \ transaction_amount AS ( \
SELECT transaction_id, SUM(amount) as amount FROM transaction_output \ SELECT transaction_id, COALESCE(SUM(amount), 0) as amount FROM transaction_output \
WHERE transaction_id IN (SELECT transaction_id FROM transaction_wallet) \ WHERE transaction_id IN (SELECT transaction_id FROM transaction_wallet) \
GROUP BY transaction_id \ GROUP BY transaction_id \
) \ ) \
SELECT t.transaction_id, t.transaction_date, a.amount, SUM(w.withdrawal) as withdrawal, t.stable_date, t.parent_date FROM `transaction` t \ SELECT t.transaction_id, t.transaction_date, a.amount, COALESCE(SUM(w.withdrawal), 0) as withdrawal, t.stable_date, t.parent_date FROM `transaction` t \
JOIN transaction_wallet w ON w.transaction_id = t.transaction_id \ JOIN transaction_wallet w ON w.transaction_id = t.transaction_id \
JOIN transaction_amount a ON a.transaction_id = t.transaction_id \ JOIN transaction_amount a ON a.transaction_id = t.transaction_id \
GROUP BY t.transaction_id \ GROUP BY t.transaction_id \
......
...@@ -134,12 +134,12 @@ export default class Shard { ...@@ -134,12 +134,12 @@ export default class Shard {
} }
console.log('[shard] database initialized'); console.log('[shard] database initialized');
this.database.shardID = this.shardID; this.database.shardID = this.shardID;
this.database.run('PRAGMA journal_mode = MEMORY', () => this.database.run('PRAGMA synchronous = OFF', () => resolve())); this.database.run('PRAGMA journal_mode = WAL', () => this.database.run('PRAGMA synchronous = NORMAL', () => resolve()));
}); });
}); });
} }
else { else {
this.database.run('PRAGMA journal_mode = MEMORY', () => this.database.run('PRAGMA synchronous = OFF', () => resolve())); this.database.run('PRAGMA journal_mode = WAL', () => this.database.run('PRAGMA synchronous = NORMAL', () => resolve()));
} }
}); });
}); });
......
...@@ -126,6 +126,6 @@ db.initialize() ...@@ -126,6 +126,6 @@ db.initialize()
}); });
} }
}); });
//millix v1.11.10-tangled //millix v1.11.11-tangled
\ No newline at end of file
...@@ -8,6 +8,7 @@ import async from 'async'; ...@@ -8,6 +8,7 @@ import async from 'async';
import walletSync from '../core/wallet/wallet-sync'; import walletSync from '../core/wallet/wallet-sync';
import peerRotation from './peer-rotation'; import peerRotation from './peer-rotation';
import statistics from '../core/statistics'; import statistics from '../core/statistics';
import wallet from '../core/wallet/wallet';
class Peer { class Peer {
...@@ -124,6 +125,26 @@ class Peer { ...@@ -124,6 +125,26 @@ class Peer {
}); });
} }
propagateTransactionList(transactions) {
const payload = {
type : 'transaction_list_propagate',
content: {transaction_id_list: transactions}
};
eventBus.emit('node_event_log', payload);
const data = JSON.stringify(payload);
network.registeredClients.forEach(ws => {
try {
ws.nodeConnectionReady && ws.send(data);
}
catch (e) {
console.log('[WARN]: try to send data over a closed connection.');
ws && ws.close();
}
});
}
transactionSend(transaction, excludeWS) { transactionSend(transaction, excludeWS) {
let payload = { let payload = {
type : 'transaction_new', type : 'transaction_new',
...@@ -677,7 +698,7 @@ class Peer { ...@@ -677,7 +698,7 @@ class Peer {
callbackCalled = true; callbackCalled = true;
reject(); reject();
} }
}, config.NETWORK_LONG_TIME_WAIT_MAX * 3); }, config.NETWORK_LONG_TIME_WAIT_MAX * 5);
} }
else { else {
reject(); reject();
...@@ -771,7 +792,29 @@ class Peer { ...@@ -771,7 +792,29 @@ class Peer {
}); });
} }
walletTransactionSync(addressKeyIdentifier, excludeTransactionList, ws) { walletTransactionSyncResponse(transactions, ws) {
const payload = {
type : 'wallet_transaction_sync_response',
content: {
transaction_id_list: transactions
}
};
eventBus.emit('node_event_log', payload);
const data = JSON.stringify(payload);
if (ws) {
try {
ws.nodeConnectionReady && ws.send(data);
}
catch (e) {
console.log('[WARN]: try to send data over a closed connection.');
ws && ws.close();
}
}
}
walletTransactionSync(addressKeyIdentifier, ws) {
if (network.registeredClients.length === 0) { if (network.registeredClients.length === 0) {
return; return;
...@@ -781,8 +824,7 @@ class Peer { ...@@ -781,8 +824,7 @@ class Peer {
let payload = { let payload = {
type : 'wallet_transaction_sync', type : 'wallet_transaction_sync',
content: { content: {
address_key_identifier : addressKeyIdentifier, address_key_identifier: addressKeyIdentifier
exclude_transaction_id_list: excludeTransactionList
} }
}; };
...@@ -841,6 +883,8 @@ class Peer { ...@@ -841,6 +883,8 @@ class Peer {
return Promise.resolve(); return Promise.resolve();
} }
wallet.flagTransactionAsRequested(transactionID);
return (forceRequestSync || options.routing ? Promise.resolve() : walletSync.getTransactionUnresolvedData(transactionID)) return (forceRequestSync || options.routing ? Promise.resolve() : walletSync.getTransactionUnresolvedData(transactionID))
.then(unresolvedTransaction => { .then(unresolvedTransaction => {
if (unresolvedTransaction) { if (unresolvedTransaction) {
...@@ -1249,7 +1293,7 @@ class Peer { ...@@ -1249,7 +1293,7 @@ class Peer {
if (this.nodeAttributeCache[content.node_id][content.attribute_type].value === content.value) { if (this.nodeAttributeCache[content.node_id][content.attribute_type].value === content.value) {
return; return;
} }
this.nodeAttributeCache[content.node_id][content.attribute_type] = content.value; this.nodeAttributeCache[content.node_id][content.attribute_type].value = content.value;
} }
statistics.newEvent('add_or_update_attribute'); statistics.newEvent('add_or_update_attribute');
......
PRAGMA foreign_keys= off;
BEGIN TRANSACTION;
CREATE INDEX idx_transaction_output_transaction_id_address_key_identifier ON transaction_output (transaction_id, address_key_identifier);
UPDATE schema_information SET value = "17" WHERE key = "version";
COMMIT;
PRAGMA foreign_keys= off;
BEGIN TRANSACTION;
CREATE INDEX idx_transaction_output_transaction_id_address_key_identifier ON transaction_output (transaction_id, address_key_identifier);
UPDATE schema_information SET value = "17" WHERE key = "version";
COMMIT;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment