Skip to content

Commit 8b66208

Browse files
committed
test: add coverage for bitcoind-knots support
1 parent 12a6745 commit 8b66208

File tree

6 files changed

+185
-2
lines changed

6 files changed

+185
-2
lines changed

src/components/network/NetworkSetting.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ const NetworkSetting: React.FC = () => {
9494
'c-lightning': settings.basePorts['c-lightning'].rest,
9595
eclair: settings.basePorts.eclair.rest,
9696
bitcoind: settings.basePorts.bitcoind.rest,
97+
'bitcoind-knots': settings.basePorts['bitcoind-knots'].rest,
9798
tapd: settings.basePorts.tapd.rest,
9899
grpcLND: settings.basePorts.LND.grpc,
99100
'grpcC-lightning': settings.basePorts['c-lightning'].grpc,
@@ -124,6 +125,11 @@ const NetworkSetting: React.FC = () => {
124125
<InputNumber />
125126
</Form.Item>
126127
</Col>
128+
<Col span={6}>
129+
<Form.Item name="bitcoind-knots" label={dockerConfigs['bitcoind-knots'].name}>
130+
<InputNumber />
131+
</Form.Item>
132+
</Col>
127133
<Col span={6}>
128134
<Form.Item name="tapd" label={dockerConfigs.tapd.name}>
129135
<InputNumber />

src/components/network/NewNetwork.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ const NewNetwork: React.FC = () => {
5555
throw new Error(l('tapdCountError'));
5656
}
5757

58+
const hasLightningNodes =
59+
values.lndNodes + values.clightningNodes + values.eclairNodes + values.litdNodes > 0;
60+
const hasBitcoinBackend = values.bitcoindNodes + values.bitcoindKnotsNodes > 0;
61+
if (hasLightningNodes && !hasBitcoinBackend) {
62+
throw new Error(l('bitcoinBackendError'));
63+
}
64+
5865
await addNetwork(values);
5966
} catch (error: any) {
6067
notify({ message: l('createError'), error });

src/i18n/locales/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@
549549
"cmps.network.NetworkSetting.saveSuccess": "Saved settings",
550550
"cmps.network.NetworkSetting.description": "Base Ports determine the starting port numbers that will be used for each node. When a network is started, Polar will use these values to detect the next open port on your machine to assign to the nodes. You usually do not need to change these unless you are running into port conflicts with other apps installed on your computer. If you change these values, try to maintain at decent size gap (roughly 100) between them to prevent them from overlapping as more nodes of each implementation are added to your networks.",
551551
"cmps.network.NewNetwork.tapdCountError": "The number of Taproot Assets nodes must be less than or equal to the number of LND nodes",
552+
"cmps.network.NewNetwork.bitcoinBackendError": "Lightning nodes require at least one Bitcoin backend (Bitcoin Core or Bitcoin Knots)",
552553
"cmps.nodeImages.CommandVariables.header": "Command Variable Substitutions",
553554
"cmps.nodeImages.CommandVariables.tableTitle": "Wrap the variables below in double braces to use them in the command",
554555
"cmps.nodeImages.CommandVariables.variable": "Variable",

src/store/models/network.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,19 @@ describe('Network model', () => {
211211
expect(node.docker.image).toBe(custom[0].dockerImage);
212212
expect(node.docker.command).toBe(custom[0].command);
213213
});
214+
215+
it('should add a network with bitcoind-knots nodes', async () => {
216+
await store.getActions().network.addNetwork({
217+
...addNetworkArgs,
218+
bitcoindNodes: 0,
219+
bitcoindKnotsNodes: 2,
220+
});
221+
const { bitcoin } = firstNetwork().nodes;
222+
expect(bitcoin).toHaveLength(2);
223+
bitcoin.forEach(node => {
224+
expect(node.implementation).toBe('bitcoind-knots');
225+
});
226+
});
214227
});
215228

216229
describe('Adding a Node', () => {
@@ -376,6 +389,21 @@ describe('Network model', () => {
376389
const { lightning } = firstNetwork().nodes;
377390
expect(lightning[5].docker.command).toBe('test-command');
378391
});
392+
393+
it('should add a bitcoind-knots node to an existing network', async () => {
394+
const knotsLatest = defaultRepoState.images['bitcoind-knots'].latest;
395+
const payload = {
396+
id: firstNetwork().id,
397+
type: 'bitcoind-knots',
398+
version: knotsLatest,
399+
};
400+
await store.getActions().network.addNode(payload);
401+
const { bitcoin } = firstNetwork().nodes;
402+
expect(bitcoin).toHaveLength(2);
403+
expect(bitcoin[1].name).toBe('backend2');
404+
expect(bitcoin[1].implementation).toBe('bitcoind-knots');
405+
expect(bitcoin[1].version).toBe(knotsLatest);
406+
});
379407
});
380408

381409
describe('Removing a Node', () => {

src/utils/network.spec.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { Network } from 'types';
1414
import { defaultRepoState } from './constants';
1515
import {
16+
createBitcoindKnotsNetworkNode,
1617
createBitcoindNetworkNode,
1718
createCLightningNetworkNode,
1819
createLitdNetworkNode,
@@ -379,6 +380,141 @@ describe('Network Utils', () => {
379380
});
380381
});
381382

383+
describe('createBitcoindKnotsNetworkNode', () => {
384+
let network: Network;
385+
386+
beforeEach(() => {
387+
network = createNetwork({
388+
id: 1,
389+
name: 'my-test',
390+
description: 'my-test-description',
391+
lndNodes: 0,
392+
clightningNodes: 0,
393+
eclairNodes: 0,
394+
bitcoindNodes: 1,
395+
bitcoindKnotsNodes: 0,
396+
tapdNodes: 0,
397+
litdNodes: 0,
398+
status: Status.Stopped,
399+
repoState: defaultRepoState,
400+
managedImages: testManagedImages,
401+
customImages: [],
402+
manualMineCount: 6,
403+
});
404+
});
405+
406+
it('should create a bitcoind-knots node with correct properties', () => {
407+
const node = createBitcoindKnotsNetworkNode(
408+
network,
409+
defaultRepoState.images['bitcoind-knots'].latest,
410+
testNodeDocker,
411+
);
412+
expect(node.name).toBe('backend2');
413+
expect(node.type).toBe('bitcoin');
414+
expect(node.implementation).toBe('bitcoind-knots');
415+
expect(node.version).toBe(defaultRepoState.images['bitcoind-knots'].latest);
416+
expect(node.status).toBe(Status.Stopped);
417+
expect(node.ports.rpc).toBeDefined();
418+
expect(node.ports.p2p).toBeDefined();
419+
expect(node.ports.zmqBlock).toBeDefined();
420+
expect(node.ports.zmqTx).toBeDefined();
421+
});
422+
423+
it('should peer with existing bitcoin nodes', () => {
424+
const node = createBitcoindKnotsNetworkNode(
425+
network,
426+
defaultRepoState.images['bitcoind-knots'].latest,
427+
testNodeDocker,
428+
);
429+
network.nodes.bitcoin.push(node);
430+
expect(node.peers).toContain('backend1');
431+
expect(network.nodes.bitcoin[0].peers).toContain('backend2');
432+
});
433+
434+
it('should have no peers when it is the first bitcoin node', () => {
435+
network.nodes.bitcoin = [];
436+
const node = createBitcoindKnotsNetworkNode(
437+
network,
438+
defaultRepoState.images['bitcoind-knots'].latest,
439+
testNodeDocker,
440+
);
441+
expect(node.peers).toHaveLength(0);
442+
});
443+
});
444+
445+
describe('createNetwork with bitcoind-knots', () => {
446+
it('should create a network with bitcoind-knots nodes', () => {
447+
const network = createNetwork({
448+
id: 1,
449+
name: 'knots-test',
450+
description: 'test with knots',
451+
lndNodes: 0,
452+
clightningNodes: 0,
453+
eclairNodes: 0,
454+
bitcoindNodes: 0,
455+
bitcoindKnotsNodes: 2,
456+
tapdNodes: 0,
457+
litdNodes: 0,
458+
status: Status.Stopped,
459+
repoState: defaultRepoState,
460+
managedImages: testManagedImages,
461+
customImages: [],
462+
manualMineCount: 6,
463+
});
464+
expect(network.nodes.bitcoin).toHaveLength(2);
465+
expect(network.nodes.bitcoin[0].implementation).toBe('bitcoind-knots');
466+
expect(network.nodes.bitcoin[1].implementation).toBe('bitcoind-knots');
467+
});
468+
469+
it('should create a network with mixed bitcoind and bitcoind-knots nodes', () => {
470+
const network = createNetwork({
471+
id: 1,
472+
name: 'mixed-test',
473+
description: 'test with mixed backends',
474+
lndNodes: 0,
475+
clightningNodes: 0,
476+
eclairNodes: 0,
477+
bitcoindNodes: 1,
478+
bitcoindKnotsNodes: 1,
479+
tapdNodes: 0,
480+
litdNodes: 0,
481+
status: Status.Stopped,
482+
repoState: defaultRepoState,
483+
managedImages: testManagedImages,
484+
customImages: [],
485+
manualMineCount: 6,
486+
});
487+
expect(network.nodes.bitcoin).toHaveLength(2);
488+
expect(network.nodes.bitcoin[0].implementation).toBe('bitcoind');
489+
expect(network.nodes.bitcoin[1].implementation).toBe('bitcoind-knots');
490+
expect(network.nodes.bitcoin[1].peers).toContain('backend1');
491+
expect(network.nodes.bitcoin[0].peers).toContain('backend2');
492+
});
493+
494+
it('should adjust bitcoind-knots version for LND compatibility when target version is available', () => {
495+
const network = createNetwork({
496+
id: 1,
497+
name: 'knots-lnd-test',
498+
description: 'test knots with lnd',
499+
lndNodes: 1,
500+
clightningNodes: 0,
501+
eclairNodes: 0,
502+
bitcoindNodes: 0,
503+
bitcoindKnotsNodes: 1,
504+
tapdNodes: 0,
505+
litdNodes: 0,
506+
status: Status.Stopped,
507+
repoState: defaultRepoState,
508+
managedImages: testManagedImages,
509+
customImages: [],
510+
manualMineCount: 6,
511+
});
512+
expect(network.nodes.bitcoin).toHaveLength(1);
513+
expect(network.nodes.bitcoin[0].implementation).toBe('bitcoind-knots');
514+
expect(network.nodes.bitcoin[0].version).toBeDefined();
515+
});
516+
});
517+
382518
describe('createNetworkNodes', () => {
383519
let network: Network;
384520

src/utils/tests/helpers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ export const testManagedImages: ManagedImage[] = [
3131
version: defaultRepoState.images.bitcoind.latest,
3232
command: '',
3333
},
34+
{
35+
implementation: 'bitcoind-knots',
36+
version: defaultRepoState.images['bitcoind-knots'].latest,
37+
command: '',
38+
},
3439
{
3540
implementation: 'tapd',
3641
version: defaultRepoState.images.tapd.latest,
@@ -191,8 +196,8 @@ export const testRepoState: DockerRepoState = {
191196
],
192197
},
193198
'bitcoind-knots': {
194-
latest: '29.0',
195-
versions: ['29.0', '28.0', '27.0', '26.0'],
199+
latest: '29.2',
200+
versions: ['29.2', '28.0', '27.0', '26.0'],
196201
},
197202
btcd: {
198203
latest: '',

0 commit comments

Comments
 (0)