Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tenanted peers #3352

Merged
merged 6 commits into from
Apr 1, 2025
Merged

Conversation

oana-lolea
Copy link
Contributor

@oana-lolea oana-lolea commented Mar 20, 2025

Added tenantId to peers.

Changes proposed in this pull request

  • Added tenantId to peers
  • Updated tests

Context

Fixes #3129

Checklist

  • Related issues linked using fixes #number
  • Tests added/updated
  • Make sure that all checks pass
  • Bruno collection updated (if necessary)
  • Documentation issue created with user-docs label (if necessary)
  • OpenAPI specs updated (if necessary)

@github-actions github-actions bot added type: tests Testing related pkg: backend Changes in the backend package. pkg: frontend Changes in the frontend package. type: source Changes business logic pkg: mock-ase pkg: mock-account-service-lib labels Mar 20, 2025
@oana-lolea oana-lolea marked this pull request as ready for review March 20, 2025 13:18
args.assetId
)
return peer ? peerToGraphql(peer) : null
}

export const createPeer: MutationResolvers<ApolloContext>['createPeer'] =
export const createPeer: MutationResolvers<ForTenantIdContext>['createPeer'] =
Copy link
Contributor

@njlie njlie Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ForTenantIdContext does not seem to be leveraged for this resolver. An assertion for ctx.forTenantId being defined should be used in resolvers using that context in order to proceed.

Perhaps the middleware that sets ctx.forTenantId could be modified to try to retrieve the input tenantId from the input asset, or there could be a more bespoke check that could be performed in this resolver instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can use TenantedApolloContext here, and then, pass ctx.isOperator ? undefined : ctx.tenant.id as the tenantId into the create.
This will ensure a non-operator tenant must own the asset its trying to create the peer with and at the same time, lets the operator create peers with any assetId (ie the operator can create peers for any tenant)

@@ -747,6 +747,8 @@ type Peer implements Model {
liquidity: UInt64
"The date and time when the peer was created."
createdAt: String!
"Unique identifier of the tenant associated with the peer."
tenantId: ID!
Copy link
Contributor

@njlie njlie Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think tenantId still needs to be added to the CreatePeerInput, so that the CreatePeer resolver can leverage the ForTenantId context.

edit: scratch that, I see that the tenant id of a created peer is determined by the tenant of the asset that is in the input.

@@ -127,8 +127,7 @@ async function initiatePeeringRequest(
authToken: outgoingHttpToken,
endpoint: peeringDetailsOrError.ilpConnectorUrl
}
},
tenantId: args.tenantId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep this one here (since the Rafiki that is initiating the peering request can create the peer for a known tenant), and remove the tenantId on L109. Then, in the acceptPeeringRequest function (called for the Rafiki instance that's receiving the peering request), we can use deps.config.operatorTenantId when creating the peer.

parent,
args,
ctx
): Promise<ResolversTypes['PeersConnection']> => {
const peerService = await ctx.container.use('peerService')
const { sortOrder, ...pagination } = args
const tenantId = ctx.isOperator ? undefined : ctx.tenant.id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add tenantId to the peers query in the GraphQL schema, such that the operator can filter peers for a specific tenant. Then, we can do:

Suggested change
const tenantId = ctx.isOperator ? undefined : ctx.tenant.id
const tenantId = ctx.isOperator ? tenantId : ctx.tenant.id

@@ -10,6 +10,7 @@ interface PeeringRequestArgs {
httpToken: string
maxPacketAmount?: number
name?: string
tenantId: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tenantId: string

since we won't be sending it over in the peering request (from this comment)

@@ -134,6 +142,11 @@ async function createPeer(
return PeerError.InvalidHTTPEndpoint
}

const asset = await deps.assetService.get(options.assetId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const asset = await deps.assetService.get(options.assetId)
const asset = await deps.assetService.get(options.assetId, options.tenantId)

so we know that the peer gets created for the correct tenant

@oana-lolea oana-lolea requested review from mkurapov and njlie March 28, 2025 12:17
@golobitch golobitch linked an issue Mar 30, 2025 that may be closed by this pull request
5 tasks
Copy link
Contributor

@sanducb sanducb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Copy link
Contributor

@mkurapov mkurapov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final few things!

args.assetId
)
return peer ? peerToGraphql(peer) : null
}

export const createPeer: MutationResolvers<ApolloContext>['createPeer'] =
export const createPeer: MutationResolvers<ForTenantIdContext>['createPeer'] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can use TenantedApolloContext here, and then, pass ctx.isOperator ? undefined : ctx.tenant.id as the tenantId into the create.
This will ensure a non-operator tenant must own the asset its trying to create the peer with and at the same time, lets the operator create peers with any assetId (ie the operator can create peers for any tenant)

@@ -177,7 +178,7 @@ export const createPeerLiquidityWithdrawal: MutationResolvers<ApolloContext>['cr
})
}
const peerService = await ctx.container.use('peerService')
const peer = await peerService.get(peerId)
const peer = await peerService.get(peerId, ctx.tenant.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const peer = await peerService.get(peerId, ctx.tenant.id)
const peer = await peerService.get(peerId, ctx.isOperator ? undefined : ctx.tenant.id)

so the operator can create liquidity withdrawals for any peer

@@ -100,7 +100,8 @@ export const depositPeerLiquidity: MutationResolvers<ApolloContext>['depositPeer
const peerOrError = await peerService.depositLiquidity({
transferId: args.input.id,
peerId: args.input.peerId,
amount: args.input.amount
amount: args.input.amount,
tenantId: ctx.tenant.id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tenantId: ctx.tenant.id
tenantId: ctx.isOperator ? undefined : ctx.tenant.id

so the operator can create liquidity deposits for any peer

@oana-lolea oana-lolea requested a review from mkurapov April 1, 2025 07:50
): Promise<Peer | undefined> {
const peer = await Peer.query(deps.knex).findById(id)
let query = Peer.query(deps.knex)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a test for this: "cannot get peer with incorrect tenantId"

Comment on lines +150 to +153
const asset = await deps.assetService.get(options.assetId, options.tenantId)
if (!asset) {
return PeerError.UnknownAsset
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a test for this: "cannot create peer with incorrect tenantId"

@oana-lolea oana-lolea merged commit ab156ad into 2893/multi-tenancy-v1 Apr 1, 2025
25 of 37 checks passed
@oana-lolea oana-lolea deleted the feature/3129-tenanted-peers branch April 1, 2025 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: backend Changes in the backend package. pkg: frontend Changes in the frontend package. pkg: mock-account-service-lib pkg: mock-ase type: source Changes business logic type: tests Testing related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Multi-Tenant] Tenanted Peers
4 participants