Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit 8aeda51

Browse files
authored
Merge pull request #109 from ArkEcosystem/mainnet-dev
Merge mainnet-dev into mainnet
2 parents 56a73a1 + bce0619 commit 8aeda51

13 files changed

Lines changed: 120 additions & 84 deletions

config.mainnet.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"port": 4001,
33
"address": "0.0.0.0",
4-
"version": "1.0.3",
4+
"version": "1.1.0",
55
"fileLogLevel": "info",
66
"logFileName": "logs/ark.log",
77
"consoleLogLevel": "info",

helpers/z_schema.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ function schema(network){
8484
}
8585
});
8686

87+
this.z_schema.registerFormat('voteString', function (str) {
88+
//Excluding capital hex characters
89+
//(mainnet database could contain mixed case vote strings?)
90+
return /^[-+]0[23][0-9a-fA-F]{64}$/.test(str);
91+
});
92+
8793
this.z_schema.registerFormat('queryList', function (obj) {
8894
obj.limit = 100;
8995
return true;

logic/account.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function Account (scope, cb) {
1717

1818
self = this;
1919
db = this.scope.db;
20-
library = this.scope.library;
20+
library = this.scope;
2121
genesisBlock = this.scope.genesisblock.block;
2222

2323
this.table = 'mem_accounts';

logic/transaction.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ Transaction.prototype.process = function (trs, sender, requester, cb) {
391391
Transaction.prototype.verify = function (trs, sender, requester, cb) {
392392
var valid = false;
393393
var err = null;
394+
const INT_32_MIN = -2147483648;
395+
const INT_32_MAX = 2147483647;
394396

395397
if (typeof requester === 'function') {
396398
cb = requester;
@@ -568,9 +570,13 @@ Transaction.prototype.verify = function (trs, sender, requester, cb) {
568570
return cb(senderBalance.error);
569571
}
570572

573+
if (trs.timestamp < INT_32_MIN || trs.timestamp > INT_32_MAX) {
574+
return cb('Invalid transaction timestamp. Timestamp is not in the int32 range.');
575+
}
576+
571577
// Check timestamp
572578
if (slots.getSlotNumber(trs.timestamp) > slots.getSlotNumber()) {
573-
return cb('Invalid transaction timestamp');
579+
return cb('Invalid transaction timestamp. Timestamp is in the future.');
574580
}
575581

576582
// Check fee

logic/vote.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ Vote.prototype.schema = {
210210
properties: {
211211
votes: {
212212
type: 'array',
213+
items: {
214+
type: 'string',
215+
format: 'voteString',
216+
},
213217
minLength: 1,
214218
maxLength: constants.maximumVotes,
215219
uniqueItems: true

modules/blocks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ Blocks.prototype.getCommonBlock = function (peer, height, cb) {
572572
if (err || res.body.error) {
573573
return waterCb(err || res.body.error.toString());
574574
} else if (!res.body.common) {
575-
return waterCb(['Chain comparison failed with peer:', peer.string, 'using ids:', ids].join(' '));
575+
return waterCb(['Chain comparison failed with peer:', peer.toString(), 'using ids:', ids].join(' '));
576576
} else {
577577
return waterCb(null, res);
578578
}
@@ -586,7 +586,7 @@ Blocks.prototype.getCommonBlock = function (peer, height, cb) {
586586
height: res.body.common.height
587587
}).then(function (rows) {
588588
if (!rows.length || !rows[0].count) {
589-
return waterCb(['Chain comparison failed with peer:', peer.string, 'using block:', JSON.stringify(res.body.common)].join(' '));
589+
return waterCb(['Chain comparison failed with peer:', peer.toString(), 'using block:', JSON.stringify(res.body.common)].join(' '));
590590
} else {
591591
return waterCb(null, res.body);
592592
}

modules/delegates.js

Lines changed: 63 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var schema = require('../schema/delegates.js');
1414
var slots = require('../helpers/slots.js');
1515
var sql = require('../sql/delegates.js');
1616
var transactionTypes = require('../helpers/transactionTypes.js');
17+
var crypto = require('crypto')
1718

1819
// Private fields
1920
var modules, library, self, __private = {}, shared = {};
@@ -62,7 +63,7 @@ __private.attachApi = function () {
6263
'get /fee': 'getFee',
6364
'get /forging/getForgedByAccount': 'getForgedByAccount',
6465
'put /': 'addDelegate',
65-
'get /getNextForgers': 'getNextForgers'
66+
'get /getNextForgers': 'getNextForgers'
6667
});
6768

6869
if (process.env.DEBUG) {
@@ -87,85 +88,85 @@ __private.attachApi = function () {
8788
tmpKepairs = {};
8889
return res.json({success: true});
8990
});
90-
}
91-
92-
router.post('/forging/enable', function (req, res) {
93-
library.schema.validate(req.body, schema.enableForging, function (err) {
94-
if (err) {
95-
return res.json({success: false, error: err[0].message});
96-
}
97-
98-
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
9991

100-
if (!checkIpInList(library.config.forging.access.whiteList, ip)) {
101-
return res.json({success: false, error: 'Access denied'});
102-
}
92+
router.post('/forging/enable', function (req, res) {
93+
library.schema.validate(req.body, schema.enableForging, function (err) {
94+
if (err) {
95+
return res.json({success: false, error: err[0].message});
96+
}
10397

104-
var keypair = library.crypto.makeKeypair(crypto.createHash('sha256').update(req.body.secret, 'utf8').digest());
98+
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
10599

106-
if (req.body.publicKey) {
107-
if (keypair.publicKey.toString('hex') !== req.body.publicKey) {
108-
return res.json({success: false, error: 'Invalid passphrase'});
100+
if (!checkIpInList(library.config.forging.access.whiteList, ip)) {
101+
return res.json({success: false, error: 'Access denied'});
109102
}
110-
}
111103

112-
if (__private.keypairs[keypair.publicKey.toString('hex')]) {
113-
return res.json({success: false, error: 'Forging is already enabled'});
114-
}
104+
var keypair = library.crypto.makeKeypair(crypto.createHash('sha256').update(req.body.secret, 'utf8').digest());
115105

116-
modules.accounts.getAccount({publicKey: keypair.publicKey.toString('hex')}, function (err, account) {
117-
if (err) {
118-
return res.json({success: false, error: err});
106+
if (req.body.publicKey) {
107+
if (keypair.publicKey.toString('hex') !== req.body.publicKey) {
108+
return res.json({success: false, error: 'Invalid passphrase'});
109+
}
119110
}
120-
if (account && account.isDelegate) {
121-
__private.keypairs[keypair.publicKey.toString('hex')] = keypair;
122-
library.logger.info('Forging enabled on account: ' + account.address);
123-
return res.json({success: true, address: account.address});
124-
} else {
125-
return res.json({success: false, error: 'Delegate not found'});
111+
112+
if (__private.keypairs[keypair.publicKey.toString('hex')]) {
113+
return res.json({success: false, error: 'Forging is already enabled'});
126114
}
115+
116+
modules.accounts.getAccount({publicKey: keypair.publicKey.toString('hex')}, function (err, account) {
117+
if (err) {
118+
return res.json({success: false, error: err});
119+
}
120+
if (account && account.isDelegate) {
121+
__private.keypairs[keypair.publicKey.toString('hex')] = keypair;
122+
library.logger.info('Forging enabled on account: ' + account.address);
123+
return res.json({success: true, address: account.address});
124+
} else {
125+
return res.json({success: false, error: 'Delegate not found'});
126+
}
127+
});
127128
});
128129
});
129-
});
130130

131-
router.post('/forging/disable', function (req, res) {
132-
library.schema.validate(req.body, schema.disableForging, function (err) {
133-
if (err) {
134-
return res.json({success: false, error: err[0].message});
135-
}
136-
137-
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
138-
139-
if (!checkIpInList(library.config.forging.access.whiteList, ip)) {
140-
return res.json({success: false, error: 'Access denied'});
141-
}
131+
router.post('/forging/disable', function (req, res) {
132+
library.schema.validate(req.body, schema.disableForging, function (err) {
133+
if (err) {
134+
return res.json({success: false, error: err[0].message});
135+
}
142136

143-
var keypair = library.crypto.makeKeypair(crypto.createHash('sha256').update(req.body.secret, 'utf8').digest());
137+
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
144138

145-
if (req.body.publicKey) {
146-
if (keypair.publicKey.toString('hex') !== req.body.publicKey) {
147-
return res.json({success: false, error: 'Invalid passphrase'});
139+
if (!checkIpInList(library.config.forging.access.whiteList, ip)) {
140+
return res.json({success: false, error: 'Access denied'});
148141
}
149-
}
150142

151-
if (!__private.keypairs[keypair.publicKey.toString('hex')]) {
152-
return res.json({success: false, error: 'Delegate not found'});
153-
}
143+
var keypair = library.crypto.makeKeypair(crypto.createHash('sha256').update(req.body.secret, 'utf8').digest());
154144

155-
modules.accounts.getAccount({publicKey: keypair.publicKey.toString('hex')}, function (err, account) {
156-
if (err) {
157-
return res.json({success: false, error: err});
145+
if (req.body.publicKey) {
146+
if (keypair.publicKey.toString('hex') !== req.body.publicKey) {
147+
return res.json({success: false, error: 'Invalid passphrase'});
148+
}
158149
}
159-
if (account && account.isDelegate) {
160-
delete __private.keypairs[keypair.publicKey.toString('hex')];
161-
library.logger.info('Forging disabled on account: ' + account.address);
162-
return res.json({success: true, address: account.address});
163-
} else {
150+
151+
if (!__private.keypairs[keypair.publicKey.toString('hex')]) {
164152
return res.json({success: false, error: 'Delegate not found'});
165153
}
154+
155+
modules.accounts.getAccount({publicKey: keypair.publicKey.toString('hex')}, function (err, account) {
156+
if (err) {
157+
return res.json({success: false, error: err});
158+
}
159+
if (account && account.isDelegate) {
160+
delete __private.keypairs[keypair.publicKey.toString('hex')];
161+
library.logger.info('Forging disabled on account: ' + account.address);
162+
return res.json({success: true, address: account.address});
163+
} else {
164+
return res.json({success: false, error: 'Delegate not found'});
165+
}
166+
});
166167
});
167168
});
168-
});
169+
}
169170

170171
router.get('/forging/status', function (req, res) {
171172
library.schema.validate(req.query, schema.forgingStatus, function (err) {
@@ -514,7 +515,7 @@ Delegates.prototype.getDelegates = function (query, cb) {
514515
var realLimit = Math.min(offset + limit, count);
515516

516517
var lastBlock = modules.blockchain.getLastBlock(),
517-
totalSupply = __private.blockReward.calcSupply(lastBlock.height);
518+
totalSupply = __private.blockReward.calcSupply(lastBlock.height);
518519

519520
for (var i = 0; i < delegates.length; i++) {
520521
delegates[i].rate = i + 1;
@@ -737,7 +738,7 @@ __private.toggleForgingOnReceipt = function () {
737738

738739

739740
// if (lastReceipt.secondsAgo > timeOut) {
740-
// return self.disableForging('timeout');
741+
// return self.disableForging('timeout');
741742
// } else {
742743
return self.enableForging();
743744
// }
@@ -879,7 +880,7 @@ shared.getDelegates = function (req, cb) {
879880
if (data.sortMethod === 'ASC') {
880881
return sorta - sortb;
881882
} else {
882-
return sortb - sorta;
883+
return sortb - sorta;
883884
}
884885
}
885886

modules/nodeManager.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ NodeManager.prototype.onBlocksReceived = function(blocks, peer, cb) {
158158
block.totalAmount = parseInt(block.totalAmount);
159159
block.totalFee = parseInt(block.totalFee);
160160
block.verified = false;
161-
block.processed = false;
161+
block.processed = false;
162+
if (block.numberOfTransactions == 0) block.transactions = [];
162163
// looks like the last block pulled, let's broadcast it
163164
block.broadcast = blocks.length == 1;
164165

@@ -499,12 +500,12 @@ NodeManager.prototype.onBlockReceived = function(block, peer, cb) {
499500
modules.blockchain.removeBlock(block);
500501
return mSequence(err, block);
501502
}
502-
modules.blockchain.upsertBlock(block);
503503
library.logger.debug("processing block with "+block.transactions.length+" transactions", block.height);
504504
return library.bus.message('verifyBlock', block, function(err){
505505
if(err){
506506
library.logger.error("Error processing block at height", block.height);
507-
modules.blockchain.removeBlock(block);
507+
} else {
508+
modules.blockchain.upsertBlock(block);
508509
}
509510
return mSequence(err, block);
510511
});

modules/transactionPool.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function TransactionPool (cb, scope) {
1818
self.unconfirmed = { };
1919
self.queued = { };
2020
self.multisignature = { };
21+
self.invalid = { };
2122

2223
// TODO: to remove
2324
self.expiryInterval = 30000;
@@ -355,20 +356,22 @@ TransactionPool.prototype.receiveTransactions = function (transactions, cb) {
355356
return eachSeriesCb();
356357
}
357358
else {
358-
// we add transaction in mempool but still can be a spam.
359-
// be sure to remove if there is an error in processing
360-
__private.mempool[transaction.id]=transaction;
359+
if (!self.invalid[transaction.id])
361360
__private.processVerifyTransaction(transaction, function (err) {
362361
if (!err) {
362+
__private.mempool[transaction.id]=transaction;
363363
return self.queueTransaction(transaction, eachSeriesCb);
364364
} else {
365-
// TODO: do we want to remove from mempool if somebody is spamming?
366-
// we delete the tx in 1 min, so max 1 verification per spammy tx
367-
// we keep the error in memory.
365+
// delete all invalid txs after 1 min
368366
transaction.error=err;
369-
setTimeout(function(){
370-
delete __private.mempool[transaction.id];
371-
}, 60000);
367+
if(JSON.stringify(self.invalid) === JSON.stringify({})) {
368+
setTimeout(function() {
369+
self.invalid = {};
370+
}, 60000)
371+
}
372+
373+
self.invalid[transaction.id] = true;
374+
372375
return eachSeriesCb(err, transaction);
373376
}
374377
});

modules/transport.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var modules, library, self, __private = {}, shared = {};
1818

1919
__private.headers = {};
2020
__private.messages = {};
21-
__private.broadcastTransactions = [];
21+
__private.broadcastTransactions = {};
2222

2323
// Constructor
2424
function Transport (cb, scope) {
@@ -27,9 +27,13 @@ function Transport (cb, scope) {
2727

2828
setInterval(function(){
2929
var maxspliced = 10;
30-
if(maxspliced > __private.broadcastTransactions.length) maxspliced = __private.broadcastTransactions.length;
30+
if(maxspliced > Object.keys(__private.broadcastTransactions).length) maxspliced = Object.keys(__private.broadcastTransactions).length;
3131
if(maxspliced > 0){
32-
var transactions = __private.broadcastTransactions.splice(0, maxspliced);
32+
var transactions = Object.keys(__private.broadcastTransactions).splice(0, maxspliced).map(tx => {
33+
var thistx = __private.broadcastTransactions[tx];
34+
delete __private.broadcastTransactions[tx];
35+
return thistx;
36+
});
3337
self.broadcast({limit: 20}, {api: '/transactions', data: {transactions: transactions}, method: 'POST'});
3438
}
3539
}, 3000);
@@ -507,7 +511,7 @@ Transport.prototype.onBroadcastTransaction = function (transaction) {
507511
delete transaction.verified;
508512
delete transaction.processed;
509513

510-
__private.broadcastTransactions.push(transaction);
514+
__private.broadcastTransactions[transaction.id] = transaction;
511515
};
512516

513517
//

0 commit comments

Comments
 (0)