444 lines
16 KiB
JavaScript
444 lines
16 KiB
JavaScript
'use strict';
|
|
var should = require('should');
|
|
var sinon = require('sinon');
|
|
var TxController = require('../lib/transactions');
|
|
var bcoin = require('bcoin');
|
|
var _ = require('lodash');
|
|
|
|
describe('Transactions', function() {
|
|
|
|
describe('/tx/:txid', function() {
|
|
|
|
it('should have correct data', function(done) {
|
|
|
|
var flosight = {
|
|
'txid': 'eac9723230b8b632117ac3d75288d6f8eb81cf1ea553eb9fd42562d5f767d54a',
|
|
'version': 1,
|
|
'locktime': 0,
|
|
'vin': [
|
|
{
|
|
'txid': '46e58a68bb9ec9b458a9599dc2bac1e1fa09ad15c29c7f923c8f6f0aa33d6456',
|
|
'vout': 1,
|
|
'sequence': 4294967295,
|
|
'n': 0,
|
|
'scriptSig': {
|
|
'hex': '47304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff3012102cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2',
|
|
'asm': '304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff301 02cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2'
|
|
},
|
|
'addr': '1NqgMfGUeELP2BfxD4hQuJSRq2d3DVJcCi',
|
|
'valueSat': 1546063700,
|
|
'value': 15.460637,
|
|
'doubleSpentTxID': null,
|
|
'isConfirmed': null,
|
|
'confirmations': null,
|
|
'unconfirmedInput': null
|
|
}
|
|
],
|
|
'vout': [
|
|
{
|
|
'value': '0.37100000',
|
|
'n': 0,
|
|
'scriptPubKey': {
|
|
'hex': '76a914bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b788ac',
|
|
'asm': 'OP_DUP OP_HASH160 bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b7 OP_EQUALVERIFY OP_CHECKSIG',
|
|
'addresses': [
|
|
'1JA8mcfrBv1YYsASAp9jtohm8x2q7LnUhs'
|
|
],
|
|
'type': 'pubkeyhash'
|
|
},
|
|
'spentHeight': null,
|
|
'spentIndex': null,
|
|
'spentTxId': null
|
|
},
|
|
{
|
|
'value': '15.08763700',
|
|
'n': 1,
|
|
'scriptPubKey': {
|
|
'hex': '76a914c2c74d7519d4425fc1a253f066d980164341554a88ac',
|
|
'asm': 'OP_DUP OP_HASH160 c2c74d7519d4425fc1a253f066d980164341554a OP_EQUALVERIFY OP_CHECKSIG',
|
|
'addresses': [
|
|
'1Jktr121Hm63qtWBMV8dCNJNW2KtWXy4fp'
|
|
],
|
|
'type': 'pubkeyhash'
|
|
},
|
|
'spentHeight': null,
|
|
'spentIndex': null,
|
|
'spentTxId': null
|
|
}
|
|
],
|
|
'blockhash': '0000000000000000009d2e9b7a984d55c6c99ba62f98e9bc7dad8b1e779045a3',
|
|
'blockheight': 481763,
|
|
'confirmations': 4,
|
|
'time': 1503507151,
|
|
'blocktime': 1503507151,
|
|
'valueOut': 15.458637,
|
|
'size': 225,
|
|
'valueIn': 15.460637,
|
|
'fees': 0.002
|
|
};
|
|
|
|
var bcoinTx = bcoin.tx.fromRaw('010000000156643da30a6f8f3c927f9cc215ad09fae1c1bac29d59a958b4c99ebb688ae546010000006a47304402203ddb49db43074b421ec6d5604ae91aac37f4715139e0c83ea1145379e8cbf02702207fbc92c4038ad501989b097844ae4e337c9388f0713110620b40e582b85fdff3012102cd90aa18ec8e3b35c0447ffc713c945cb837429d33d075d1b0f050c72ea838d2ffffffff02e0193602000000001976a914bc345e0e0e5b0dbddb7b35ef3430fedd528dd1b788ac34e8ed59000000001976a914c2c74d7519d4425fc1a253f066d980164341554a88ac00000000', 'hex');
|
|
|
|
bcoinTx.__blockhash = '0000000000000000009d2e9b7a984d55c6c99ba62f98e9bc7dad8b1e779045a3';
|
|
bcoinTx.blockhash = '0000000000000000009d2e9b7a984d55c6c99ba62f98e9bc7dad8b1e779045a3';
|
|
bcoinTx.__height = 481763;
|
|
bcoinTx.__inputValues = [ 1546063700 ];
|
|
bcoinTx.__timestamp = 1503507151;
|
|
bcoinTx.inputSatoshis = [ 1546063700 ];
|
|
bcoinTx.feeSatoshis = 200000;
|
|
bcoinTx.outputSatoshis = 1545863700;
|
|
|
|
var node = {
|
|
services: {
|
|
block: {
|
|
getTip: sinon.stub().returns({ height: 481766 })
|
|
},
|
|
transaction: {
|
|
getDetailedTransaction: sinon.stub().callsArgWith(2, null, bcoinTx)
|
|
}
|
|
}
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
var txid = 'eac9723230b8b632117ac3d75288d6f8eb81cf1ea553eb9fd42562d5f767d54a';
|
|
var req = {
|
|
params: {
|
|
txid: txid
|
|
}
|
|
};
|
|
|
|
var res = {};
|
|
var next = function() {
|
|
should(req.transaction).eql(flosight);
|
|
done();
|
|
};
|
|
|
|
transactions.transaction(req, res, next);
|
|
});
|
|
});
|
|
|
|
describe('/txs', function() {
|
|
|
|
var sandbox = sinon.sandbox.create();
|
|
|
|
afterEach(function() {
|
|
sandbox.restore();
|
|
});
|
|
|
|
it('by block hash', function(done) {
|
|
|
|
var blockOverview = {
|
|
hash: '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7',
|
|
height: 533974,
|
|
chainWork: '0000000000000000000000000000000000000000000000054626b1839ade284a',
|
|
prevHash: '00000000000001a55f3214e9172eb34b20e0bc5bd6b8007f3f149fca2c8991a4',
|
|
txids: [
|
|
'9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5'
|
|
]
|
|
};
|
|
|
|
var bcoinTx = bcoin.tx.fromRaw('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010bffffffff0100f2052a010000004341047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac00000000', 'hex');
|
|
|
|
bcoinTx.__blockhash = '000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd';
|
|
bcoinTx.blockhash = '000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd';
|
|
bcoinTx.__height = 2;
|
|
bcoinTx.__inputValues = [ 1546063700 ];
|
|
bcoinTx.__timestamp = 1231469744;
|
|
bcoinTx.inputSatoshis = [ 1546063700 ];
|
|
bcoinTx.feeSatoshis = 0;
|
|
bcoinTx.outputSatoshis = 5000000000;
|
|
|
|
var node = {
|
|
|
|
services: {
|
|
block: {
|
|
getTip: sinon.stub().returns({ height: 481773 }),
|
|
getBlockOverview: sinon.stub().callsArgWith(1, null, blockOverview),
|
|
},
|
|
|
|
transaction: {
|
|
getDetailedTransaction: sinon.stub().callsArgWith(2, null, bcoinTx)
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
|
|
var flosight = {
|
|
'pagesTotal': 1,
|
|
'txs': [
|
|
{
|
|
'txid': '9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5',
|
|
'version': 1,
|
|
'locktime': 0,
|
|
'vin': [
|
|
{
|
|
'coinbase': '04ffff001d010b',
|
|
'sequence': 4294967295,
|
|
'n': 0
|
|
}
|
|
],
|
|
'vout': [
|
|
{
|
|
'value': '50.00000000',
|
|
'n': 0,
|
|
'scriptPubKey': {
|
|
'hex': '41047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac',
|
|
'asm': '047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77 OP_CHECKSIG',
|
|
'addresses': [
|
|
'1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1'
|
|
],
|
|
'type': 'pubkeyhash'
|
|
},
|
|
'spentHeight': null,
|
|
'spentIndex': null,
|
|
'spentTxId': null
|
|
}
|
|
],
|
|
'blockhash': '000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd',
|
|
'blockheight': 2,
|
|
'confirmations': 481772,
|
|
'time': 1231469744,
|
|
'blocktime': 1231469744,
|
|
'isCoinBase': true,
|
|
'valueOut': 50,
|
|
'size': 134
|
|
}
|
|
]
|
|
};
|
|
|
|
var req = {
|
|
query: {
|
|
block: '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7'
|
|
}
|
|
};
|
|
|
|
var res = {
|
|
jsonp: function(data) {
|
|
should(data).eql(flosight);
|
|
done();
|
|
}
|
|
};
|
|
|
|
transactions.list(req, res);
|
|
});
|
|
|
|
it('by address, single/coinbase', function(done) {
|
|
|
|
var hex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3103835807244d696e656420627920416e74506f6f6c6a2f4542312f4144362f4e59412f1d205999aaa02b1200001fff0200ffffffff026fb2a54c000000001976a914ad7309dfc032d7f6b652e0c29ee353e63fffec6688ac0000000000000000266a24aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c8100000000';
|
|
|
|
var bcoinTx = bcoin.tx.fromRaw(hex, 'hex');
|
|
bcoinTx.__height = 481411;
|
|
bcoinTx.outputSatoshis = 1285927535;
|
|
bcoinTx.__timestamp = 1503242912;
|
|
bcoinTx.__blockhash = '000000000000000000926a0cd4a05ef116514cbf1852edc306d13eb951ec0b54';
|
|
bcoinTx.blockhash = '000000000000000000926a0cd4a05ef116514cbf1852edc306d13eb951ec0b54';
|
|
|
|
var node = {
|
|
services: {
|
|
block: {
|
|
getTip: sinon.stub().returns({ height: 534223 })
|
|
},
|
|
address: {
|
|
getAddressHistory: sinon.stub().callsArgWith(2, null, {
|
|
totalCount: 1,
|
|
from: 0,
|
|
to: 0xffffffff,
|
|
items: [bcoinTx]
|
|
})
|
|
}
|
|
}
|
|
};
|
|
|
|
var flosight = {
|
|
'pagesTotal': 1,
|
|
'txs': [
|
|
{
|
|
'txid': '1c01a2090db0850e1f1049bea02e4bbf44b6790dfeb8e054f2beb69339ef52d4',
|
|
'version': 1,
|
|
'locktime': 0,
|
|
'vin': [
|
|
{
|
|
'coinbase': '03835807244d696e656420627920416e74506f6f6c6a2f4542312f4144362f4e59412f1d205999aaa02b1200001fff0200',
|
|
'sequence': 4294967295,
|
|
'n': 0
|
|
}
|
|
],
|
|
'vout': [
|
|
{
|
|
'value': '12.85927535',
|
|
'n': 0,
|
|
'scriptPubKey': {
|
|
'hex': '76a914ad7309dfc032d7f6b652e0c29ee353e63fffec6688ac',
|
|
'asm': 'OP_DUP OP_HASH160 ad7309dfc032d7f6b652e0c29ee353e63fffec66 OP_EQUALVERIFY OP_CHECKSIG',
|
|
'addresses': [
|
|
'1Gp7iCzDGMZiV55Kt8uKsux6VyoHe1aJaN'
|
|
],
|
|
'type': 'pubkeyhash'
|
|
},
|
|
'spentHeight': null,
|
|
'spentIndex': null,
|
|
'spentTxId': null
|
|
},
|
|
{
|
|
'value': '0.00000000',
|
|
'n': 1,
|
|
'scriptPubKey': {
|
|
'hex': '6a24aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81',
|
|
'asm': 'OP_RETURN aa21a9ed55882e9fed16c5d3b6d77e4160a56f58c70d354d02888a99486125b638231c81'
|
|
},
|
|
'spentHeight': null,
|
|
'spentIndex': null,
|
|
'spentTxId': null
|
|
}
|
|
],
|
|
'blockhash': '000000000000000000926a0cd4a05ef116514cbf1852edc306d13eb951ec0b54',
|
|
'blockheight': 481411,
|
|
'confirmations': 52813,
|
|
'time': 1503242912,
|
|
'blocktime': 1503242912,
|
|
'isCoinBase': true,
|
|
'valueOut': 12.85927535,
|
|
'size': 181
|
|
}
|
|
]
|
|
};
|
|
|
|
var req = {
|
|
query: {
|
|
address: 'mkPvAKZ2rar6qeG3KjBtJHHMSP1wFZH7Er'
|
|
}
|
|
};
|
|
|
|
var res = {
|
|
jsonp: function(data) {
|
|
should(data).eql(flosight);
|
|
done();
|
|
}
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
transactions.list(req, res);
|
|
});
|
|
});
|
|
|
|
describe('/rawtx/:txid', function() {
|
|
|
|
it('should give the correct data', function(done) {
|
|
var hex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2303d6250800feb0aae355fe263600000963676d696e6572343208ae5800000000000000ffffffff01c018824a000000001976a91468bedce8982d25c3b6b03f6238cbad00378b8ead88ac00000000';
|
|
|
|
var node = {
|
|
services: {
|
|
block: {
|
|
getTip: sinon.stub().returns({ height: 534233 })
|
|
},
|
|
transaction: {
|
|
getTransaction: sinon.stub().callsArgWith(1, null, bcoin.tx.fromRaw(new Buffer(hex, 'hex')))
|
|
}
|
|
}
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
|
|
var txid = '25a988e54b02e0e5df146a0f8fa7b9db56210533a9f04bdfda5f4ceb6f77aadd';
|
|
var res = {};
|
|
var req = {
|
|
params: {
|
|
txid: txid
|
|
}
|
|
};
|
|
var next = function() {
|
|
should(req.rawTransaction.rawtx).eql(hex);
|
|
done();
|
|
};
|
|
transactions.rawTransaction(req, res, next);
|
|
});
|
|
});
|
|
|
|
describe('#transformInvTransaction', function() {
|
|
|
|
it('should give the correct data', function() {
|
|
var flosight = {
|
|
'txid': 'a15a7c257af596704390d345ff3ea2eed4cd02ce8bfb8afb700bff82257e49fb',
|
|
'valueOut': 0.02038504,
|
|
'vout': [
|
|
{
|
|
'3DQYCLG6rZdtV2Xw8y4YtozZjNHYoKsLuo': 45000
|
|
},
|
|
{
|
|
'12WvZmssxT85f81dD6wcmWznxbnFkEpNMS': 1993504
|
|
}
|
|
],
|
|
'isRBF': false
|
|
};
|
|
|
|
var rawTx = '01000000011760bc271a397bfb65b7506d430d96ebb1faff467ed957516238a9670e806a86010000006b483045022100f0056ae68a34cdb4194d424bd727c18f82653bca2a198e0d55ab6b4ee88bbdb902202a5745af4f72a5dbdca1e3d683af4667728a8b20e8001e0f8308a4d329ce3f96012102f3af6e66b61c9d99c74d9a9c3c1bec014a8c05d28bf339c8f5f395b5ce319e7dffffffff02c8af00000000000017a9148083b541ea15f1d18c5ca5e1fd47f9035cce24ed87206b1e00000000001976a91410a0e70cd91a45e0e6e409e227ab285bd61592b188ac00000000';
|
|
var tx = bcoin.tx.fromRaw(rawTx, 'hex');
|
|
|
|
var node = {
|
|
services: { block: { getTip: sinon.stub().returns({ height: 534233 }) } },
|
|
network: 'livenet'
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
|
|
var result = transactions.transformInvTransaction(tx);
|
|
should(result).eql(flosight);
|
|
});
|
|
|
|
it('will not include null values in vout array', function() {
|
|
var flosight = {
|
|
'txid': '716d54157c31e52c820494c6c2b8af1b64352049f4dcc80632aa15742a7f82c4',
|
|
'valueOut': 12.5002,
|
|
'vout': [
|
|
{
|
|
'n4eY3qiP9pi32MWC6FcJFHciSsfNiYFYgR': 12.5002 * 1e8
|
|
}
|
|
],
|
|
'isRBF': false
|
|
};
|
|
|
|
var rawTx = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0403ebc108ffffffff04a0ca814a000000001976a914fdb9fb622b0db8d9121475a983288a0876f4de4888ac0000000000000000226a200000000000000000000000000000000000000000000000000000ffff0000000000000000000000001b6a1976a914fdb9fb622b0db8d9121475a983288a0876f4de4888ac0000000000000000326a303a791c8e85200500d89769b4f958e4db6b3ec388ddaa30233c4517d942d440c24ae903bff40d97ca06465fcf2714000000000000';
|
|
var tx = bcoin.tx.fromRaw(rawTx, 'hex');
|
|
|
|
var node = {
|
|
services: { block: { getTip: sinon.stub().returns({ height: 534233 }) } },
|
|
network: 'testnet'
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
|
|
var result = transactions.transformInvTransaction(tx);
|
|
should(result).eql(flosight);
|
|
});
|
|
|
|
it('should detect RBF txs', function() {
|
|
var testCases = [
|
|
{
|
|
rawTx: '01000000017fa897c3556271c34cb28c03c196c2d912093264c9d293cb4980a2635474467d010000000f5355540b6f93598893578893588851ffffffff01501e0000000000001976a914aa2482ce71d219018ef334f6cc551ee88abd920888ac00000000',
|
|
expected: false,
|
|
}, {
|
|
rawTx: '01000000017fa897c3556271c34cb28c03c196c2d912093264c9d293cb4980a2635474467d010000000f5355540b6f935988935788935888510000000001501e0000000000001976a914aa2482ce71d219018ef334f6cc551ee88abd920888ac00000000',
|
|
expected: true,
|
|
},
|
|
];
|
|
|
|
var node = {
|
|
services: { block: { getTip: sinon.stub().returns({ height: 534233 }) } },
|
|
network: 'livenet'
|
|
};
|
|
|
|
var transactions = new TxController(node);
|
|
|
|
_.each(testCases, function(tc) {
|
|
var tx = bcoin.tx.fromRaw(tc.rawTx, 'hex');
|
|
var result = transactions.transformInvTransaction(tx);
|
|
should.exist(result.isRBF);
|
|
result.isRBF.should.equal(tc.expected);
|
|
});
|
|
});
|
|
|
|
});
|
|
});
|