Skip to content

Commit

Permalink
Merge branch 'main' into docs-peering-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
brad-dow committed Dec 17, 2024
2 parents e5d0502 + ee45d61 commit fc6dcc2
Show file tree
Hide file tree
Showing 24 changed files with 215 additions and 104 deletions.
36 changes: 33 additions & 3 deletions .github/workflows/node-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ jobs:
push: false
platforms: ${{ matrix.platform.arch }}
file: packages/${{ matrix.package }}/Dockerfile.prod
tags: ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}:${{ needs.version-generator.outputs.version }}
tags: ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}-${{ matrix.platform.name }}:${{ needs.version-generator.outputs.version }}
outputs: type=docker,dest=/tmp/${{ github.sha }}-${{ matrix.package }}-${{ matrix.platform.name }}-${{ needs.version-generator.outputs.version }}.tar
- name: Save docker image to cache
uses: actions/cache@v4
Expand All @@ -291,6 +291,7 @@ jobs:
- backend
- frontend
steps:
- uses: actions/checkout@v4
- name: Fetch docker image from cache
uses: actions/cache/restore@v4
with:
Expand Down Expand Up @@ -326,6 +327,7 @@ jobs:
- backend
- frontend
steps:
- uses: actions/checkout@v4
- name: Fetch docker image from cache
uses: actions/cache/restore@v4
with:
Expand Down Expand Up @@ -380,11 +382,38 @@ jobs:
run: docker images
- name: Push to registry
run: |
docker push ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}:${{ needs.version-generator.outputs.version }}
docker push ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}-${{ matrix.platform.name }}:${{ needs.version-generator.outputs.version }}
push-manifest:
name: Push multi-arch manifest list
needs: [version-generator, push]
runs-on: ubuntu-latest
if: needs.version-generator.outputs.dockerPush == 'true'
strategy:
matrix:
package:
- auth
- backend
- frontend
steps:
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create manifest list
run: |
docker manifest create ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}:${{ needs.version-generator.outputs.version }} \
--amend ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}-amd64:${{ needs.version-generator.outputs.version }} \
--amend ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}-arm64:${{ needs.version-generator.outputs.version }}
- name: Push manifest list
run: |
docker manifest push ghcr.io/${{ github.repository_owner }}/rafiki-${{ matrix.package }}:${{ needs.version-generator.outputs.version }}
generate-release:
runs-on: ubuntu-latest
needs: [push, version-generator]
needs: [push-manifest, version-generator]
if: needs.version-generator.outputs.generateRelease == 'true'
steps:
- name: Checkout Code
Expand All @@ -395,6 +424,7 @@ jobs:
with:
token: ${{ github.token }}
tag: ${{ needs.version-generator.outputs.version }}
includeRefIssues: false
- name: Create Release
uses: ncipollo/[email protected]
with:
Expand Down
2 changes: 2 additions & 0 deletions .grype.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignore:
- vulnerability: GHSA-3xgq-45jj-v275
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ build
**/styles/*.css
.docusaurus
.cache-loader
packages/documentation/**
.astro
1 change: 1 addition & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CVE-2024-21538 exp:2024-12-31
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
"license": "Apache-2.0",
"repository": "https://github.com/interledger/rafiki",
"engines": {
"pnpm": "^8.15.4",
"pnpm": "^8.15.9",
"node": "20"
},
"packageManager": "[email protected].5",
"packageManager": "[email protected].9",
"scripts": {
"preinstall": "npx only-allow pnpm",
"lint": "eslint --max-warnings=0 --fix .",
Expand Down Expand Up @@ -78,7 +78,8 @@
"tar@<6.2.1": ">=6.2.1",
"braces@<3.0.3": ">=3.0.3",
"@grpc/grpc-js@>=1.10.0 <1.10.9": ">=1.10.9",
"dset@<3.1.4": ">=3.1.4"
"dset@<3.1.4": ">=3.1.4",
"cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5"
}
}
}
2 changes: 1 addition & 1 deletion packages/backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export class App {

if (this.config.adminApiSecret) {
koa.use(async (ctx, next: Koa.Next): Promise<void> => {
if (!verifyApiSignature(ctx, this.config)) {
if (!(await verifyApiSignature(ctx, this.config))) {
ctx.throw(401, 'Unauthorized')
}
return next()
Expand Down
11 changes: 11 additions & 0 deletions packages/backend/src/payment-method/local/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ describe('LocalPaymentService', (): void => {
scale: 2
})

assetMap['USD_9'] = await createAsset(deps, {
code: 'USD_9',
scale: 9
})

assetMap['EUR'] = await createAsset(deps, {
code: 'EUR',
scale: 2
Expand All @@ -67,6 +72,10 @@ describe('LocalPaymentService', (): void => {
assetId: assetMap['USD'].id
})

walletAddressMap['USD_9'] = await createWalletAddress(deps, {
assetId: assetMap['USD_9'].id
})

walletAddressMap['EUR'] = await createWalletAddress(deps, {
assetId: assetMap['EUR'].id
})
Expand Down Expand Up @@ -261,6 +270,7 @@ describe('LocalPaymentService', (): void => {
${'EUR'} | ${100n} | ${'USD'} | ${100n} | ${1.0} | ${'cross currency, same rate'}
${'EUR'} | ${100n} | ${'USD'} | ${112n} | ${0.9} | ${'cross currency, exchange rate < 1'}
${'EUR'} | ${100n} | ${'USD'} | ${50n} | ${2.0} | ${'cross currency, exchange rate > 1'}
${'USD_9'} | ${100_000_000n} | ${'USD'} | ${10n} | ${1.0} | ${'local currency, different scale'}
`(
'$description',
async ({
Expand All @@ -270,6 +280,7 @@ describe('LocalPaymentService', (): void => {
expectedDebitAmount,
exchangeRate
}): Promise<void> => {
if (incomingAssetCode !== 'USD_9') return
let ratesScope

if (incomingAssetCode !== debitAssetCode) {
Expand Down
20 changes: 11 additions & 9 deletions packages/backend/src/rates/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { convertSource, Asset, convertDestination } from './util'

describe('Rates util', () => {
describe('convert', () => {
describe('convert same scales', () => {
describe('convertSource', () => {
describe('convertSource same scales', () => {
test.each`
exchangeRate | sourceAmount | assetScale | expectedResult | description
${1.5} | ${100n} | ${9} | ${{ amount: 150n, scaledExchangeRate: 1.5 }} | ${'exchange rate above 1'}
Expand Down Expand Up @@ -31,11 +31,12 @@ describe('Rates util', () => {
)
})

describe('convert different scales', () => {
describe('convertSource different scales', () => {
test.each`
exchangeRate | sourceAmount | sourceAssetScale | destinationAssetScale | expectedResult | description
${1.5} | ${100n} | ${9} | ${12} | ${{ amount: 150_000n, scaledExchangeRate: 1500 }} | ${'convert scale from low to high'}
${1.5} | ${100_000n} | ${12} | ${9} | ${{ amount: 150n, scaledExchangeRate: 0.0015 }} | ${'convert scale from high to low'}
exchangeRate | sourceAmount | sourceAssetScale | destinationAssetScale | expectedResult | description
${1.5} | ${100n} | ${9} | ${12} | ${{ amount: 150_000n, scaledExchangeRate: 1500 }} | ${'convert scale from low to high'}
${1.5} | ${100_000n} | ${12} | ${9} | ${{ amount: 150n, scaledExchangeRate: 0.0015 }} | ${'convert scale from high to low'}
${1} | ${100_000_000n} | ${9} | ${2} | ${{ amount: 10n, scaledExchangeRate: 0.0000001 }} | ${'exchange rate of 1 with different scale'}
`(
'$description',
async ({
Expand All @@ -57,7 +58,7 @@ describe('Rates util', () => {
)
})
})
describe('convert reverse', () => {
describe('convertDestination', () => {
describe('convert same scales', () => {
test.each`
exchangeRate | destinationAmount | assetScale | expectedResult | description
Expand Down Expand Up @@ -88,8 +89,9 @@ describe('Rates util', () => {
describe('convert different scales', () => {
test.each`
exchangeRate | destinationAmount | sourceAssetScale | destinationAssetScale | expectedResult | description
${2.0} | ${100n} | ${9} | ${12} | ${{ amount: 50_000n, scaledExchangeRate: 0.002 }} | ${'convert scale from low to high'}
${2.0} | ${100_000n} | ${12} | ${9} | ${{ amount: 50n, scaledExchangeRate: 2000 }} | ${'convert scale from high to low'}
${2.0} | ${100n} | ${12} | ${9} | ${{ amount: 50_000n, scaledExchangeRate: 0.002 }} | ${'convert scale from low to high'}
${2.0} | ${100_000n} | ${9} | ${12} | ${{ amount: 50n, scaledExchangeRate: 2000 }} | ${'convert scale from high to low'}
${1} | ${100_000_000n} | ${2} | ${9} | ${{ amount: 10n, scaledExchangeRate: 10000000 }} | ${'convert scale from high to low (same asset)'}
`(
'$description',
async ({
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/rates/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function convertSource(opts: ConvertSourceOptions): ConvertResults {
export function convertDestination(
opts: ConvertDestinationOptions
): ConvertResults {
const scaleDiff = opts.sourceAsset.scale - opts.destinationAsset.scale
const scaleDiff = opts.destinationAsset.scale - opts.sourceAsset.scale
const scaledExchangeRate = opts.exchangeRate * 10 ** scaleDiff

return {
Expand Down
59 changes: 51 additions & 8 deletions packages/backend/src/telemetry/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { Counter, Histogram } from '@opentelemetry/api'
import { privacy } from './privacy'
import { mockRatesApi } from '../tests/rates'
import { ConvertResults } from '../rates/util'

jest.mock('@opentelemetry/api', () => ({
...jest.requireActual('@opentelemetry/api'),
Expand Down Expand Up @@ -355,14 +356,17 @@ describe('Telemetry Service', () => {
expect(internalConvertSpy).not.toHaveBeenCalled()
})

it('should apply privacy', async () => {
it('should apply privacy by default', async () => {
const convertedAmount = 500n

jest
//"any" to access private ts class member variable
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.spyOn(telemetryService as any, 'convertAmount')
.mockImplementation(() => Promise.resolve(convertedAmount))
.mockResolvedValueOnce({
scaledExchangeRate: 1,
amount: convertedAmount
} as ConvertResults)
const applyPrivacySpy = jest
.spyOn(privacy, 'applyPrivacy')
.mockReturnValue(123)
Expand All @@ -378,14 +382,49 @@ describe('Telemetry Service', () => {
value: 100n,
assetCode: 'USD',
assetScale: 2
}
},
undefined
)

expect(applyPrivacySpy).toHaveBeenCalledWith(Number(convertedAmount))
expect(incrementCounterSpy).toHaveBeenCalledWith(counterName, 123, {})
})

it('should not apply privacy if preservePrivacy is false', async () => {
const convertedAmount = 500n

jest
//"any" to access private ts class member variable
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.spyOn(telemetryService as any, 'convertAmount')
.mockResolvedValueOnce({
scaledExchangeRate: 1,
amount: convertedAmount
} as ConvertResults)

const applyPrivacySpy = jest.spyOn(privacy, 'applyPrivacy')
const incrementCounterSpy = jest.spyOn(
telemetryService,
'incrementCounter'
)

const counterName = 'test_counter'
await telemetryService.incrementCounterWithTransactionAmount(
counterName,
{
value: 100n,
assetCode: 'USD',
assetScale: 2
},
undefined,
false
)

expect(applyPrivacySpy).not.toHaveBeenCalled()
expect(incrementCounterSpy).toHaveBeenCalledWith(
counterName,
123,
expect.any(Object)
Number(convertedAmount),
{}
)
})

Expand Down Expand Up @@ -421,7 +460,10 @@ describe('Telemetry Service', () => {
//"any" to access private ts class member variable
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.spyOn(telemetryService as any, 'convertAmount')
.mockImplementation(() => Promise.resolve(10000n))
.mockResolvedValueOnce({
scaledExchangeRate: 1,
amount: 100n
} as ConvertResults)
const incrementCounterSpy = jest.spyOn(
telemetryService,
'incrementCounter'
Expand All @@ -437,14 +479,15 @@ describe('Telemetry Service', () => {
value: 100n,
assetCode: 'USD',
assetScale: 2
}
},
{ attribute: 'metric attribute' }
)

expect(convertSpy).toHaveBeenCalled()
expect(incrementCounterSpy).toHaveBeenCalledWith(
counterName,
obfuscatedAmount,
expect.any(Object)
{ attribute: 'metric attribute' }
)
})
})
Expand Down
11 changes: 5 additions & 6 deletions packages/backend/src/telemetry/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,13 @@ export class TelemetryServiceImpl implements TelemetryService {
return
}

const obfuscatedAmount = preservePrivacy
? privacy.applyPrivacy(Number(converted))
: Number(converted)
this.incrementCounter(name, obfuscatedAmount, attributes)
const finalAmount = preservePrivacy
? privacy.applyPrivacy(Number(converted.amount))
: Number(converted.amount)
this.incrementCounter(name, finalAmount, attributes)
} catch (e) {
this.deps.logger.error(e, `Unable to collect telemetry`)
this.deps.logger.error(e, 'Unable to collect telemetry')
}
return Promise.resolve()
}

public recordHistogram(
Expand Down
15 changes: 12 additions & 3 deletions packages/documentation/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ export default defineConfig({
src: '/scripts.js',
defer: true
}
},
{
tag: 'script',
attrs: {
defer: true,
'data-website-id': '75fba178-7dca-4874-adc9-50cf85c83528',
src: 'https://ilf-site-analytics.netlify.app/script.js',
'data-domains': 'rafiki.dev'
}
}
],
logo: {
Expand Down Expand Up @@ -263,9 +272,9 @@ export default defineConfig({
],
plugins: [
starlightLinksValidator({
errorOnLocalLinks: false,
}),
],
errorOnLocalLinks: false
})
]
}),
GraphQL({
schema: '../backend/src/graphql/schema.graphql',
Expand Down
2 changes: 2 additions & 0 deletions packages/documentation/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ hero:
link: /overview/overview
icon: open-book
variant: primary
attrs:
data-umami-event: Landing page - Rafiki docs
---

import { Card, CardGrid } from '@astrojs/starlight/components'
Expand Down
Loading

0 comments on commit fc6dcc2

Please sign in to comment.