UNPKG

@node-lightning/wire

Version:
306 lines (256 loc) 10.8 kB
/* eslint-disable mocha/no-async-describe */ /* eslint-disable @typescript-eslint/no-misused-promises */ /* eslint-disable @typescript-eslint/require-await */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-floating-promises */ import { ShortChannelId } from "@node-lightning/core"; import { ILogger } from "@node-lightning/logger"; import { expect } from "chai"; import Sinon from "sinon"; import { ChannelRangeQuery, ChannelRangeQueryState } from "../../lib/gossip/ChannelRangeQuery"; import { QueryChannelRangeMessage } from "../../lib/messages/QueryChannelRangeMessage"; import { ReplyChannelRangeMessage } from "../../lib/messages/ReplyChannelRangeMessage"; import { IMessageSender } from "../../lib/Peer"; import { createFakeLogger, createFakePeer } from "../_test-utils"; describe("ChannelRangeQuery", () => { let chainHash: Buffer; let sut: ChannelRangeQuery; let peer: Sinon.SinonStubbedInstance<IMessageSender>; let logger: ILogger; beforeEach(() => { chainHash = Buffer.alloc(32, 1); peer = createFakePeer(); logger = createFakeLogger(); sut = new ChannelRangeQuery(chainHash, peer, logger); }); describe(".queryRange()", () => { describe("with defaults", async () => { it("should send query_channel_range", () => { sut.queryRange(); const msg = peer.sendMessage.args[0][0] as QueryChannelRangeMessage; expect(msg.firstBlocknum).to.equal(0); expect(msg.numberOfBlocks).to.equal(4294967295); }); it("should be in active state", () => { sut.queryRange(); expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); }); describe("with options", () => { it("should send query_channel_range", () => { sut.queryRange(1000000, 1000); const msg = peer.sendMessage.args[0][0] as QueryChannelRangeMessage; expect(msg.firstBlocknum).to.equal(1000000); expect(msg.numberOfBlocks).to.equal(1000); }); it("should be in active state", () => { sut.queryRange(1000000, 1000); expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); }); describe("with overflow", () => { it("should send query_channel_range", () => { sut.queryRange(1000); const msg = peer.sendMessage.args[0][0] as QueryChannelRangeMessage; expect(msg.firstBlocknum).to.equal(1000); expect(msg.numberOfBlocks).to.equal(4294966295); }); it("should be in active state", () => { sut.queryRange(1000); expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); }); }); describe("error reply", () => { let promise: Promise<ShortChannelId[]>; beforeEach(() => { promise = sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = false; msg.firstBlocknum = 0; msg.numberOfBlocks = 1000; sut.handleReplyChannelRange(msg); }); it("should reject with error", done => { promise.catch(() => done()); }); it("transitions to failed", () => { promise.catch(() => { expect(sut.state).to.equal(ChannelRangeQueryState.Failed); }); }); }); describe("multiple errors", () => { it("should reject with single error", done => { const promise = sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = false; msg.firstBlocknum = 0; msg.numberOfBlocks = 1000; sut.handleReplyChannelRange(msg); sut.handleReplyChannelRange(msg); promise.catch(() => done()); }); }); describe("multiple success", () => { it("should resolve with single success", async () => { const promise = sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.firstBlocknum = 0; msg.numberOfBlocks = 1000; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); sut.handleReplyChannelRange(msg); sut.handleReplyChannelRange(msg); await promise; }); }); describe("single reply", () => { let promise: Promise<ShortChannelId[]>; beforeEach(() => { promise = sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.firstBlocknum = 0; msg.numberOfBlocks = 1000; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); sut.handleReplyChannelRange(msg); }); it("should returns scids", async () => { const scids = await promise; expect(scids).to.deep.equal([new ShortChannelId(1, 1, 1)]); }); it("transitions to complete", async () => { await promise; expect(sut.state).to.equal(ChannelRangeQueryState.Complete); }); }); describe("multi reply incomplete", () => { beforeEach(() => { sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.firstBlocknum = 0; msg.numberOfBlocks = 500; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); sut.handleReplyChannelRange(msg); }); it("should enqueue scids", () => { expect(sut.results).to.deep.equal([new ShortChannelId(1, 1, 1)]); }); it("stays in active state", () => { expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); }); describe("multi reply complete", () => { let promise: Promise<ShortChannelId[]>; beforeEach(() => { promise = sut.queryRange(0, 1000); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.firstBlocknum = 0; msg.numberOfBlocks = 500; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); sut.handleReplyChannelRange(msg); const msg2 = new ReplyChannelRangeMessage(); msg2.fullInformation = true; msg2.firstBlocknum = 500; msg2.numberOfBlocks = 500; msg2.shortChannelIds.push(new ShortChannelId(500, 1, 1)); sut.handleReplyChannelRange(msg2); }); it("should enqueue scids", async () => { const scids = await promise; expect(scids).to.deep.equal([ new ShortChannelId(1, 1, 1), new ShortChannelId(500, 1, 1), ]); }); it("state should be complete", async () => { await promise; expect(sut.state).to.equal(ChannelRangeQueryState.Complete); }); }); describe("detect legacy", () => { describe("full_info=false, with_scids=true", () => { beforeEach(() => { sut.queryRange(0, 4294967295); (sut as any)._isLegacy = true; const msg = new ReplyChannelRangeMessage(); msg.fullInformation = false; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); msg.firstBlocknum = 1000; msg.numberOfBlocks = 8000; sut.handleReplyChannelRange(msg); }); it("should be active", async () => { expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); it("should be legacy", async () => { expect(sut.isLegacy).to.be.true; }); }); }); describe("when isLegacy", () => { let promise: Promise<ShortChannelId[]>; beforeEach(() => { (sut as any)._isLegacy = true; }); describe("full_info=true, with_scids=true", () => { beforeEach(() => { promise = sut.queryRange(0, 4294967295); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); msg.firstBlocknum = 1000; msg.numberOfBlocks = 8000; sut.handleReplyChannelRange(msg); }); it("should emit complete", async () => { const scids = await promise; expect(scids).to.deep.equal([new ShortChannelId(1, 1, 1)]); }); it("should be in complete state", async () => { await promise; expect(sut.state).to.equal(ChannelRangeQueryState.Complete); }); }); describe("full_info=true, with_scids=false", () => { beforeEach(() => { promise = sut.queryRange(0, 4294967295); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = true; msg.firstBlocknum = 1000; msg.numberOfBlocks = 8000; msg.shortChannelIds = []; sut.handleReplyChannelRange(msg); }); it("should error", done => { promise.catch(() => done()); }); it("should be in failed state", done => { promise.catch(() => { expect(sut.state).to.equal(ChannelRangeQueryState.Failed); done(); }); }); }); describe("full_info=false, with_scids=true", () => { beforeEach(() => { promise = sut.queryRange(0, 4294967295); const msg = new ReplyChannelRangeMessage(); msg.fullInformation = false; msg.firstBlocknum = 1000; msg.numberOfBlocks = 8000; msg.shortChannelIds.push(new ShortChannelId(1, 1, 1)); sut.handleReplyChannelRange(msg); }); it("should enqueue results", () => { expect(sut.results).to.deep.equal([new ShortChannelId(1, 1, 1)]); }); it("should still be active", () => { expect(sut.state).to.equal(ChannelRangeQueryState.Active); }); }); }); });