Rebased using the update lightning interfaces
This commit is contained in:
parent
eb90434c28
commit
80f1ee45b5
@ -249,7 +249,7 @@ export default class CLightningClient extends EventEmitter implements AbstractLi
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
nodes: listnodes['nodes'].map(node => convertNode(node)),
|
nodes: listnodes['nodes'].map(node => convertNode(node)),
|
||||||
channels: channelsList,
|
edges: channelsList,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,19 @@ export function convertNode(clNode: any): ILightningApi.Node {
|
|||||||
alias: clNode.alias ?? '',
|
alias: clNode.alias ?? '',
|
||||||
color: `#${clNode.color ?? ''}`,
|
color: `#${clNode.color ?? ''}`,
|
||||||
features: [], // TODO parse and return clNode.feature
|
features: [], // TODO parse and return clNode.feature
|
||||||
public_key: clNode.nodeid,
|
pub_key: clNode.nodeid,
|
||||||
sockets: clNode.addresses?.map(addr => `${addr.address}:${addr.port}`) ?? [],
|
addresses: clNode.addresses?.map((addr) => {
|
||||||
updated_at: new Date((clNode?.last_timestamp ?? 0) * 1000).toUTCString(),
|
return {
|
||||||
|
network: addr.type,
|
||||||
|
addr: `${addr.address}:${addr.port}`
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
last_update: clNode?.last_timestamp ?? 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert clightning "listchannels" response to lnd "describegraph.channels" format
|
* Convert clightning "listchannels" response to lnd "describegraph.edges" format
|
||||||
*/
|
*/
|
||||||
export function convertAndmergeBidirectionalChannels(clChannels: any[]): ILightningApi.Channel[] {
|
export function convertAndmergeBidirectionalChannels(clChannels: any[]): ILightningApi.Channel[] {
|
||||||
const consolidatedChannelList: ILightningApi.Channel[] = [];
|
const consolidatedChannelList: ILightningApi.Channel[] = [];
|
||||||
@ -41,67 +46,58 @@ export function convertNode(clNode: any): ILightningApi.Node {
|
|||||||
return consolidatedChannelList;
|
return consolidatedChannelList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertChannelId(channelId): string {
|
||||||
|
const s = channelId.split('x').map(part => parseInt(part));
|
||||||
|
return BigInt((s[0] << 40) | (s[1] << 16) | s[2]).toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert two clightning "getchannels" entries into a full a lnd "describegraph.channels" format
|
* Convert two clightning "getchannels" entries into a full a lnd "describegraph.edges" format
|
||||||
* In this case, clightning knows the channel policy for both nodes
|
* In this case, clightning knows the channel policy for both nodes
|
||||||
*/
|
*/
|
||||||
function buildFullChannel(clChannelA: any, clChannelB: any): ILightningApi.Channel {
|
function buildFullChannel(clChannelA: any, clChannelB: any): ILightningApi.Channel {
|
||||||
const lastUpdate = Math.max(clChannelA.last_update ?? 0, clChannelB.last_update ?? 0);
|
const lastUpdate = Math.max(clChannelA.last_update ?? 0, clChannelB.last_update ?? 0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: clChannelA.short_channel_id,
|
channel_id: clChannelA.short_channel_id,
|
||||||
capacity: clChannelA.satoshis,
|
capacity: clChannelA.satoshis,
|
||||||
transaction_id: '', // TODO
|
last_update: lastUpdate,
|
||||||
transaction_vout: 0, // TODO
|
node1_policy: convertPolicy(clChannelA),
|
||||||
updated_at: new Date(lastUpdate * 1000).toUTCString(),
|
node2_policy: convertPolicy(clChannelB),
|
||||||
policies: [
|
chan_point: ':0', // TODO
|
||||||
convertPolicy(clChannelA),
|
node1_pub: clChannelA.source,
|
||||||
convertPolicy(clChannelB)
|
node2_pub: clChannelB.source,
|
||||||
]
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert one clightning "getchannels" entry into a full a lnd "describegraph.channels" format
|
* Convert one clightning "getchannels" entry into a full a lnd "describegraph.edges" format
|
||||||
* In this case, clightning knows the channel policy of only one node
|
* In this case, clightning knows the channel policy of only one node
|
||||||
*/
|
*/
|
||||||
function buildIncompleteChannel(clChannel: any): ILightningApi.Channel {
|
function buildIncompleteChannel(clChannel: any): ILightningApi.Channel {
|
||||||
return {
|
return {
|
||||||
id: clChannel.short_channel_id,
|
channel_id: clChannel.short_channel_id,
|
||||||
capacity: clChannel.satoshis,
|
capacity: clChannel.satoshis,
|
||||||
policies: [convertPolicy(clChannel), getEmptyPolicy()],
|
last_update: clChannel.last_update ?? 0,
|
||||||
transaction_id: '', // TODO
|
node1_policy: convertPolicy(clChannel),
|
||||||
transaction_vout: 0, // TODO
|
node2_policy: null,
|
||||||
updated_at: new Date((clChannel.last_update ?? 0) * 1000).toUTCString(),
|
chan_point: ':0', // TODO
|
||||||
|
node1_pub: clChannel.source,
|
||||||
|
node2_pub: clChannel.destination,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a clightning "listnode" response to a lnd channel policy format
|
* Convert a clightning "listnode" response to a lnd channel policy format
|
||||||
*/
|
*/
|
||||||
function convertPolicy(clChannel: any): ILightningApi.Policy {
|
function convertPolicy(clChannel: any): ILightningApi.RoutingPolicy {
|
||||||
return {
|
return {
|
||||||
public_key: clChannel.source,
|
time_lock_delta: 0, // TODO
|
||||||
base_fee_mtokens: clChannel.base_fee_millisatoshi,
|
min_htlc: clChannel.htlc_minimum_msat.slice(0, -4),
|
||||||
fee_rate: clChannel.fee_per_millionth,
|
max_htlc_msat: clChannel.htlc_maximum_msat.slice(0, -4),
|
||||||
is_disabled: !clChannel.active,
|
fee_base_msat: clChannel.base_fee_millisatoshi,
|
||||||
max_htlc_mtokens: clChannel.htlc_maximum_msat.slice(0, -4),
|
fee_rate_milli_msat: clChannel.fee_per_millionth,
|
||||||
min_htlc_mtokens: clChannel.htlc_minimum_msat.slice(0, -4),
|
disabled: !clChannel.active,
|
||||||
updated_at: new Date((clChannel.last_update ?? 0) * 1000).toUTCString(),
|
last_update: clChannel.last_update ?? 0,
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an empty channel policy in lnd format
|
|
||||||
*/
|
|
||||||
function getEmptyPolicy(): ILightningApi.Policy {
|
|
||||||
return {
|
|
||||||
public_key: 'null',
|
|
||||||
base_fee_mtokens: '0',
|
|
||||||
fee_rate: 0,
|
|
||||||
is_disabled: true,
|
|
||||||
max_htlc_mtokens: '0',
|
|
||||||
min_htlc_mtokens: '0',
|
|
||||||
updated_at: new Date(0).toUTCString(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import { IEsploraApi } from '../../api/bitcoin/esplora-api.interface';
|
|||||||
import { ILightningApi } from '../../api/lightning/lightning-api.interface';
|
import { ILightningApi } from '../../api/lightning/lightning-api.interface';
|
||||||
import { $lookupNodeLocation } from './sync-tasks/node-locations';
|
import { $lookupNodeLocation } from './sync-tasks/node-locations';
|
||||||
import lightningApi from '../../api/lightning/lightning-api-factory';
|
import lightningApi from '../../api/lightning/lightning-api-factory';
|
||||||
|
import { convertChannelId } from '../../api/lightning/clightning/clightning-convert';
|
||||||
|
|
||||||
class NodeSyncService {
|
class NodeSyncService {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
@ -320,7 +321,7 @@ class NodeSyncService {
|
|||||||
;`;
|
;`;
|
||||||
|
|
||||||
await DB.query(query, [
|
await DB.query(query, [
|
||||||
channel.channel_id,
|
this.toIntegerId(channel.channel_id),
|
||||||
this.toShortId(channel.channel_id),
|
this.toShortId(channel.channel_id),
|
||||||
channel.capacity,
|
channel.capacity,
|
||||||
txid,
|
txid,
|
||||||
@ -391,8 +392,7 @@ class NodeSyncService {
|
|||||||
|
|
||||||
private async $saveNode(node: ILightningApi.Node): Promise<void> {
|
private async $saveNode(node: ILightningApi.Node): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const updatedAt = this.utcDateToMysql(node.last_update);
|
const sockets = (node.addresses?.map(a => a.addr).join(',')) ?? '';
|
||||||
const sockets = node.addresses.map(a => a.addr).join(',');
|
|
||||||
const query = `INSERT INTO nodes(
|
const query = `INSERT INTO nodes(
|
||||||
public_key,
|
public_key,
|
||||||
first_seen,
|
first_seen,
|
||||||
@ -401,15 +401,16 @@ class NodeSyncService {
|
|||||||
color,
|
color,
|
||||||
sockets
|
sockets
|
||||||
)
|
)
|
||||||
VALUES (?, NOW(), ?, ?, ?, ?) ON DUPLICATE KEY UPDATE updated_at = ?, alias = ?, color = ?, sockets = ?;`;
|
VALUES (?, NOW(), FROM_UNIXTIME(?), ?, ?, ?)
|
||||||
|
ON DUPLICATE KEY UPDATE updated_at = FROM_UNIXTIME(?), alias = ?, color = ?, sockets = ?`;
|
||||||
|
|
||||||
await DB.query(query, [
|
await DB.query(query, [
|
||||||
node.pub_key,
|
node.pub_key,
|
||||||
updatedAt,
|
node.last_update,
|
||||||
node.alias,
|
node.alias,
|
||||||
node.color,
|
node.color,
|
||||||
sockets,
|
sockets,
|
||||||
updatedAt,
|
node.last_update,
|
||||||
node.alias,
|
node.alias,
|
||||||
node.color,
|
node.color,
|
||||||
sockets,
|
sockets,
|
||||||
@ -419,8 +420,19 @@ class NodeSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toIntegerId(id: string): string {
|
||||||
|
if (config.LIGHTNING.BACKEND === 'lnd') {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
return convertChannelId(id);
|
||||||
|
}
|
||||||
|
|
||||||
/** Decodes a channel id returned by lnd as uint64 to a short channel id */
|
/** Decodes a channel id returned by lnd as uint64 to a short channel id */
|
||||||
private toShortId(id: string): string {
|
private toShortId(id: string): string {
|
||||||
|
if (config.LIGHTNING.BACKEND === 'cln') {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
const n = BigInt(id);
|
const n = BigInt(id);
|
||||||
return [
|
return [
|
||||||
n >> 40n, // nth block
|
n >> 40n, // nth block
|
||||||
|
Loading…
x
Reference in New Issue
Block a user