-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
211 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
packages/app-dassie/src/ilp-connector/functions/send-link-local-packet.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { nanoid } from "nanoid" | ||
|
||
import { | ||
type IlpPreparePacket, | ||
type IlpResponsePacket, | ||
IlpType, | ||
serializeIlpPacket, | ||
} from "@dassie/lib-protocol-ilp" | ||
import { createDeferred } from "@dassie/lib-reactive" | ||
|
||
import type { AccountPath } from "../../accounting/types/account-paths" | ||
import type { DassieReactor } from "../../base/types/dassie-base" | ||
import { OutstandingRequestsStore } from "../../local-ilp/stores/outstanding-requests" | ||
import type { NodeId } from "../../peer-protocol/types/node-id" | ||
import type { LocalEndpointInfo } from "../senders/send-local-packets" | ||
import type { PeerEndpointInfo } from "../senders/send-peer-packets" | ||
import { ProcessPreparePacket } from "./process-prepare-packet" | ||
|
||
interface SendLinkLocalPacketParameters { | ||
packet: IlpPreparePacket | ||
peerId: NodeId | ||
} | ||
|
||
export function SendLinkLocalPacket(reactor: DassieReactor) { | ||
const processPreparePacket = reactor.use(ProcessPreparePacket) | ||
const outstandingRequestsStore = reactor.use(OutstandingRequestsStore) | ||
return async function sendLinkLocalPacket({ | ||
packet, | ||
peerId, | ||
}: SendLinkLocalPacketParameters): Promise<IlpResponsePacket> { | ||
const requestId = nanoid() | ||
const deferred = createDeferred<IlpResponsePacket>() | ||
|
||
if (packet.amount !== 0n) { | ||
throw new Error( | ||
"This function only supports link-local packets with zero amount", | ||
) | ||
} | ||
|
||
outstandingRequestsStore.act.addRequest(requestId, deferred.resolve) | ||
|
||
const parsedPacket = { | ||
type: IlpType.Prepare, | ||
data: packet, | ||
} | ||
|
||
const sourceEndpointInfo: LocalEndpointInfo = { | ||
type: "local", | ||
hint: "Link Local Sender", | ||
localIlpAddressPart: "link-local", | ||
} | ||
|
||
const destinationEndpointInfo: PeerEndpointInfo = { | ||
type: "peer", | ||
nodeId: peerId, | ||
accountPath: "invalid" as AccountPath, | ||
} | ||
|
||
processPreparePacket({ | ||
sourceEndpointInfo, | ||
parsedPacket, | ||
serializedPacket: serializeIlpPacket(parsedPacket), | ||
requestId, | ||
predeterminedOutcome: { | ||
destinationEndpointInfo, | ||
outgoingAmount: 0n, | ||
outgoingExpiry: packet.expiresAt, | ||
transfers: [], | ||
}, | ||
}) | ||
|
||
return deferred | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
packages/app-dassie/src/peer-protocol/failures/uplink-address-query.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Failure } from "@dassie/lib-type-utils" | ||
|
||
export default class UplinkAddressQueryFailure extends Failure { | ||
readonly name = "UplinkAddressQueryFailure" | ||
|
||
constructor(public readonly message: string) { | ||
super() | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
packages/app-dassie/src/peer-protocol/functions/query-uplink-address.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { | ||
ILDCP_ADDRESS, | ||
ILDCP_CONDITION, | ||
parseIldcpResponse, | ||
} from "@dassie/lib-protocol-ildcp" | ||
import { IlpType, timestampToInterledgerTime } from "@dassie/lib-protocol-ilp" | ||
import { isFailure } from "@dassie/lib-type-utils" | ||
|
||
import type { DassieReactor } from "../../base/types/dassie-base" | ||
import { MAXIMUM_HOLD_TIME } from "../../ilp-connector/constants/expiry-constraints" | ||
import { SendLinkLocalPacket } from "../../ilp-connector/functions/send-link-local-packet" | ||
import type { DassieIlpAddress } from "../../ilp-connector/types/ilp-address" | ||
import UplinkAddressQueryFailure from "../failures/uplink-address-query" | ||
import type { NodeId } from "../types/node-id" | ||
|
||
export function QueryUplinkAddress(reactor: DassieReactor) { | ||
const sendLinkLocalPacket = reactor.use(SendLinkLocalPacket) | ||
|
||
return async function queryUplinkAddress(peerId: NodeId) { | ||
const ildcpRequestPacket = { | ||
amount: 0n, | ||
destination: ILDCP_ADDRESS, | ||
executionCondition: ILDCP_CONDITION, | ||
expiresAt: timestampToInterledgerTime(Date.now() + MAXIMUM_HOLD_TIME), | ||
data: new Uint8Array(), | ||
} | ||
|
||
const result = await sendLinkLocalPacket({ | ||
packet: ildcpRequestPacket, | ||
peerId, | ||
}) | ||
|
||
if (result.type === IlpType.Reject) { | ||
return new UplinkAddressQueryFailure( | ||
"ILDCP Request Was Rejected: " + result.data.message, | ||
) | ||
} | ||
|
||
const ildcpResponse = parseIldcpResponse(result.data.data) | ||
|
||
if (isFailure(ildcpResponse)) { | ||
return new UplinkAddressQueryFailure( | ||
"Failed to parse ILDCP response: " + ildcpResponse.message, | ||
) | ||
} | ||
|
||
return ildcpResponse.address as DassieIlpAddress | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
packages/app-dassie/src/peer-protocol/receive-address-from-uplink.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { createActor, createMapped } from "@dassie/lib-reactive" | ||
import { isFailure, tell } from "@dassie/lib-type-utils" | ||
|
||
import type { DassieReactor } from "../base/types/dassie-base" | ||
import { peerProtocol as logger } from "../logger/instances" | ||
import { PeersSignal } from "./computed/peers" | ||
import { QueryUplinkAddress } from "./functions/query-uplink-address" | ||
import { UplinkAddressesStore } from "./stores/uplink-addresses" | ||
|
||
export const ReceiveAddressFromUplinkActor = (reactor: DassieReactor) => { | ||
const queryUplinkAddress = reactor.use(QueryUplinkAddress) | ||
const uplinkAddressesStore = reactor.use(UplinkAddressesStore) | ||
return createMapped(reactor, PeersSignal, (peerId) => | ||
createActor((sig) => { | ||
tell(async () => { | ||
const uplinkAddress = await queryUplinkAddress(peerId) | ||
|
||
// Ignore result if the actor is already disposed | ||
if (sig.isDisposed) return | ||
|
||
if (isFailure(uplinkAddress)) { | ||
logger.error("failed to get address from uplink") | ||
uplinkAddressesStore.act.updateAddress(peerId, undefined) | ||
return | ||
} | ||
|
||
uplinkAddressesStore.act.updateAddress(peerId, uplinkAddress) | ||
}) | ||
}), | ||
) | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/app-dassie/src/peer-protocol/stores/uplink-addresses.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { enableMapSet, produce } from "immer" | ||
|
||
import { createStore } from "@dassie/lib-reactive" | ||
|
||
import type { IlpAddress } from "../../ilp-connector/types/ilp-address" | ||
import type { NodeId } from "../types/node-id" | ||
|
||
enableMapSet() | ||
|
||
export const UplinkAddressesStore = () => | ||
createStore(new Map<NodeId, IlpAddress>()).actions({ | ||
updateAddress: (peer: NodeId, newAddress: IlpAddress | undefined) => | ||
produce((draft) => { | ||
if (!newAddress) { | ||
draft.delete(peer) | ||
return | ||
} | ||
draft.set(peer, newAddress) | ||
}), | ||
}) |