node: update http for addrindex

This commit is contained in:
Braydon Fuller 2019-04-15 21:25:12 -07:00
parent 06ef0e3615
commit 4c8f11ed34
No known key found for this signature in database
GPG Key ID: F24F232D108B3AD4
3 changed files with 100 additions and 11 deletions

View File

@ -153,7 +153,8 @@ class FullNode extends Node {
port: this.config.uint('http-port'),
apiKey: this.config.str('api-key'),
noAuth: this.config.bool('no-auth'),
cors: this.config.bool('cors')
cors: this.config.bool('cors'),
maxTxs: this.config.uint('max-txs')
});
// Indexers
@ -175,7 +176,8 @@ class FullNode extends Node {
blocks: this.blocks,
chain: this.chain,
memory: this.config.bool('memory'),
prefix: this.config.filter('index').str('prefix') || this.config.prefix
prefix: this.config.filter('index').str('prefix') || this.config.prefix,
maxTxs: this.config.uint('max-txs')
});
}
@ -461,14 +463,18 @@ class FullNode extends Node {
* Retrieve transactions pertaining to an
* address from the mempool or chain database.
* @param {Address} addr
* @param {Object} options
* @param {Number} options.limit
* @param {Number} options.reverse
* @param {Buffer} options.after
* @returns {Promise} - Returns {@link TXMeta}[].
*/
async getMetaByAddress(addr) {
async getMetaByAddress(addr, options = {}) {
const mempool = this.mempool.getMetaByAddress(addr);
if (this.txindex && this.addrindex) {
const hashes = await this.addrindex.getHashesByAddress(addr);
const hashes = await this.addrindex.getHashesByAddress(addr, options);
const mtxs = [];
for (const hash of hashes) {

View File

@ -193,12 +193,20 @@ class HTTP extends Server {
this.get('/tx/address/:address', async (req, res) => {
const valid = Validator.fromRequest(req);
const address = valid.str('address');
const limit = valid.uint('limit', this.options.maxTxs);
const reverse = valid.bool('reverse', false);
const after = valid.brhash('after', null);
enforce(address, 'Address is required.');
enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.');
enforce(limit <= this.options.maxTxs,
`Limit above max of ${this.options.maxTxs}.`);
const addr = Address.fromString(address, this.network);
const metas = await this.node.getMetaByAddress(addr);
const metas = await this.node.getMetaByAddress(
addr, {limit, reverse, after});
const result = [];
for (const meta of metas) {
@ -635,6 +643,7 @@ class HTTPOptions {
this.apiHash = sha256.digest(Buffer.from(this.apiKey, 'ascii'));
this.noAuth = false;
this.cors = false;
this.maxTxs = 100;
this.prefix = null;
this.host = '127.0.0.1';
@ -721,6 +730,11 @@ class HTTPOptions {
this.certFile = options.certFile;
}
if (options.maxTxs != null) {
assert(Number.isSafeInteger(options.maxTxs));
this.maxTxs = options.maxTxs;
}
// Allow no-auth implicitly
// if we're listening locally.
if (!options.apiKey) {

View File

@ -208,8 +208,16 @@ describe('Indexer', function() {
const vectors = [
// Secret for the vectors:
// cVDJUtDjdaM25yNVVDLLX3hcHUfth4c7tY3rSc4hy9e8ibtCuj6G
{addr: 'bcrt1qngw83fg8dz0k749cg7k3emc7v98wy0c7azaa6h', amount: 19.99},
{addr: 'muZpTpBYhxmRFuCjLc7C6BBDF32C8XVJUi', amount: 1.99}
{
addr: 'bcrt1qngw83fg8dz0k749cg7k3emc7v98wy0c7azaa6h',
amount: 19.99,
label: 'p2wpkh'
},
{
addr: 'muZpTpBYhxmRFuCjLc7C6BBDF32C8XVJUi',
amount: 1.99,
label: 'p2pkh'
}
];
const txids = [];
@ -295,8 +303,8 @@ describe('Indexer', function() {
await node.close();
});
it('will get txs by address', async () => {
for (const v of vectors) {
for (const v of vectors) {
it(`will get txs by ${v.label} address`, async () => {
const res = await nclient.request(
'GET', `/tx/address/${v.addr}`, {});
@ -304,7 +312,68 @@ describe('Indexer', function() {
for (const tx of res)
assert(txids.includes(tx.hash));
}
});
});
it(`will get txs by ${v.label} address (limit)`, async () => {
const res = await nclient.request(
'GET', `/tx/address/${v.addr}`, {limit: 3});
for (const tx of res)
assert(txids.includes(tx.hash));
});
it(`txs by ${v.label} address (reverse)`, async () => {
const asc = await nclient.request(
'GET', `/tx/address/${v.addr}`, {reverse: false});
const dsc = await nclient.request(
'GET', `/tx/address/${v.addr}`, {reverse: true});
for (let i = 0; i < dsc.length; i++)
assert.equal(asc[i].hash, dsc[dsc.length - i - 1].hash);
});
it(`txs by ${v.label} address after txid`, async () => {
const one = await nclient.request(
'GET', `/tx/address/${v.addr}`, {limit: 3});
assert.strictEqual(one.length, 3);
const hash = one[2].hash;
const two = await nclient.request(
'GET', `/tx/address/${v.addr}`, {after: hash, limit: 3});
assert.strictEqual(one.length, 3);
const all = await nclient.request(
'GET', `/tx/address/${v.addr}`, {limit: 6});
assert.strictEqual(one.length, 3);
assert.deepEqual(one.concat(two), all);
});
it(`txs by ${v.label} address after txid (reverse)`, async () => {
const one = await nclient.request(
'GET', `/tx/address/${v.addr}`,
{limit: 3, reverse: true});
assert.strictEqual(one.length, 3);
const hash = one[2].hash;
const two = await nclient.request(
'GET', `/tx/address/${v.addr}`,
{after: hash, limit: 3, reverse: true});
assert.strictEqual(one.length, 3);
const all = await nclient.request(
'GET', `/tx/address/${v.addr}`,
{limit: 6, reverse: true});
assert.strictEqual(one.length, 3);
assert.deepEqual(one.concat(two), all);
});
}
});
});