Merge pull request #233 from koirikivi/verifymessage-broadcasttx

Add support for verifymessage and better error reporting for sendrawtransaction
This commit is contained in:
Manuel Aráoz 2014-11-06 14:45:14 -03:00
commit 1b647758f1
5 changed files with 151 additions and 4 deletions

View File

@ -0,0 +1,27 @@
'use strict';
var common = require('./common');
var Rpc = require('../../lib/Rpc');
exports.verify = function(req, res) {
var address = req.param('address'),
signature = req.param('signature'),
message = req.param('message');
if(typeof(address) == 'undefined'
|| typeof(signature) == 'undefined'
|| typeof(message) == 'undefined') {
return common.handleErrors({
message: 'Missing parameters (expected "address", "signature" and "message")',
code: 1
}, res);
}
Rpc.verifyMessage(address, signature, message, function(err, result) {
if (err) {
return common.handleErrors(err, res);
}
res.json({'result' : result});
});
};

View File

@ -6,6 +6,7 @@
var Address = require('../models/Address');
var async = require('async');
var common = require('./common');
var util = require('util');
var Rpc = require('../../lib/Rpc');
@ -14,7 +15,21 @@ var bdb = require('../../lib/BlockDb').default();
exports.send = function(req, res) {
Rpc.sendRawTransaction(req.body.rawtx, function(err, txid) {
if (err) return common.handleErrors(err, res);
if (err) {
var message;
if(err.code == -25) {
message = util.format(
'Generic error %s (code %s)',
err.message, err.code);
} else if(err.code == -26) {
message = util.format(
'Transaction rejected by network (code %s). Reason: %s',
err.code, err.message);
} else {
message = util.format('%s (code %s)', err.message, err.code);
}
return res.status(400).send(message);
}
res.json({'txid' : txid});
});
};

View File

@ -60,6 +60,11 @@ module.exports = function(app) {
app.get(apiPrefix + '/email/validate', emailPlugin.validate);
}
// Address routes
var messages = require('../app/controllers/messages');
app.get(apiPrefix + '/messages/verify', messages.verify);
app.post(apiPrefix + '/messages/verify', messages.verify);
//Home route
var index = require('../app/controllers/index');
app.get(apiPrefix + '/version', index.version);

View File

@ -97,15 +97,25 @@ Rpc.getBlock = function(hash, cb) {
};
Rpc.sendRawTransaction = function(rawtx, cb) {
var self = this;
bitcoreRpc.sendRawTransaction(rawtx, function(err, txid) {
if (err && err.code === -5) return cb(err); // transaction already in block chain
if (err) return cb(self.errMsg(err));
if (err) return cb(err);
return cb(err, txid.result);
});
};
Rpc.verifyMessage = function(address, signature, message, cb) {
var self = this;
bitcoreRpc.verifyMessage(address, signature, message, function(err, message) {
if (err && (err.code === -3 || err.code === -5))
return cb(err); // -3 = invalid address, -5 = malformed base64 / etc.
if (err)
return cb(self.errMsg(err));
return cb(err, message.result);
});
};
module.exports = require('soop')(Rpc);

View File

@ -0,0 +1,90 @@
#!/usr/bin/env node
'use strict';
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var assert = require('assert'),
config = require('../../config/config'),
messages = require('../../app/controllers/messages'),
correctMessage = 'test2',
correctAddress,
correctSignature;
if(config.network === 'livenet') {
correctAddress = '16Q7eRty2LrpAWvP3VTtaXXCMZj2v4xm57',
correctSignature = 'HERpcxkyOezkBPPwvUUAaxYXR/9X/8eyVjp8WKGYl7Aw8'
+ 'pMsiMXDWXf8G1t/SOUEWy94I+KA/SrBKYs2LfIHA0Q=';
} else {
correctAddress = 'mhtJo5nZLcreM5Arrf8EDABpCevp2MfmCW',
correctSignature = 'G/y2UhjZ4qBPLQGmOhl/4p/EIwTHIO1iq95kPxDk9RjYr'
+ '1JKL6dsCSuhXat7VLTGwAM3PdgRh/jwGxi6x6dNeSE=';
}
function createMockReq(body) {
// create a simplified mock of express' request object, suitable for the
// needs of test cases in this file
return {
body: body,
param: function(name) {
return this.body[name];
}
};
}
describe('messages.verify', function() {
it('should return true with correct message', function(done) {
var mockReq = createMockReq({
address: correctAddress,
signature: correctSignature,
message: correctMessage
});
var mockRes = {
json: function(data) {
assert.deepEqual(data, {
result: true,
});
done();
}
};
messages.verify(mockReq, mockRes);
});
it('should return false with incorrect message', function(done) {
var mockReq = createMockReq({
address: correctAddress,
signature: correctSignature,
message: 'NOPE'
});
var mockRes = {
json: function(data) {
assert.deepEqual(data, {
result: false,
});
done();
}
};
messages.verify(mockReq, mockRes);
});
it('should return error with incorrect parameters', function(done) {
var mockReq = createMockReq({
address: correctAddress,
message: correctMessage
});
var mockRes = {
status: function(code) {
assert.equal(code, 400);
return this;
},
send: function(data) {
assert.ok(data.match(/^Missing parameters/),
"Match not found, got '" + data + "' instead")
done();
}
};
messages.verify(mockReq, mockRes);
});
});