Skip to content

Commit

Permalink
eligible deals per allocator - filecoin-station/spark-stats#196
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
  • Loading branch information
bajtos committed Sep 2, 2024
1 parent 4eb36be commit 3839c69
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ Number of deals grouped by miner IDs.
}
```

### `GET /allocator/:id/deals/eligible/summary`

Parameters:
- `allocatorId` - an allocator id like `f03015751`

Response:

Number of deals grouped by miner IDs.

```json
{
"allocatorId": "f03015751",
"dealCount": 4088,
"clients": [
{
"clientId": "f03144229",
"dealCount": 2488
},
{
"clientId": "f03150656",
"dealCount": 1600
}
]
}
```

## Development

### Database
Expand Down
29 changes: 29 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const handler = async (req, res, client, domain) => {
await getSummaryOfEligibleDealsForMiner(req, res, client, segs[1])
} else if (segs[0] === 'client' && segs[1] && segs[2] === 'deals' && segs[3] === 'eligible' && segs[4] === 'summary' && req.method === 'GET') {
await getSummaryOfEligibleDealsForClient(req, res, client, segs[1])
} else if (segs[0] === 'allocator' && segs[1] && segs[2] === 'deals' && segs[3] === 'eligible' && segs[4] === 'summary' && req.method === 'GET') {
await getSummaryOfEligibleDealsForAllocator(req, res, client, segs[1])
} else if (segs[0] === 'inspect-request' && req.method === 'GET') {
await inspectRequest(req, res)
} else {
Expand Down Expand Up @@ -360,6 +362,33 @@ const getSummaryOfEligibleDealsForClient = async (_req, res, client, clientId) =
json(res, body)
}

const getSummaryOfEligibleDealsForAllocator = async (_req, res, client, allocatorId) => {
/** @type {{rows: {client_id: string; deal_count: number}[]}} */
const { rows } = await client.query(`
SELECT ac.client_id, COUNT(cid)::INTEGER as deal_count
FROM allocator_clients ac
LEFT JOIN retrievable_deals rd ON ac.client_id = rd.client_id
WHERE ac.allocator_id = $1 AND expires_at > now()
GROUP BY ac.client_id
ORDER BY deal_count DESC, ac.client_id ASC
`, [
allocatorId
])

// Cache the response for 6 hours
res.setHeader('cache-control', `max-age=${6 * 3600}`)

const body = {
allocatorId,
dealCount: rows.reduce((sum, row) => sum + row.deal_count, 0),
clients: rows.map(
// eslint-disable-next-line camelcase
({ client_id, deal_count }) => ({ clientId: client_id, dealCount: deal_count })
)
}
json(res, body)
}

export const inspectRequest = async (req, res) => {
await json(res, {
remoteAddress: req.socket.remoteAddress,
Expand Down
38 changes: 38 additions & 0 deletions api/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,15 @@ describe('Routes', () => {
('bafyexpired', 'f0230', 'f0800', '2020-01-01')
ON CONFLICT DO NOTHING
`)

await client.query(`
INSERT INTO allocator_clients (allocator_id, client_id)
VALUES
('f0500', 'f0800'),
('f0500', 'f0810'),
('f0520', 'f0820')
ON CONFLICT DO NOTHING
`)
})

describe('GET /miner/{id}/deals/eligible/summary', () => {
Expand Down Expand Up @@ -723,5 +732,34 @@ describe('Routes', () => {
})
})
})

describe('GET /allocator/{id}/deals/eligible/summary', () => {
it('returns deal counts grouped by client id', async () => {
const res = await fetch(`${spark}/allocator/f0500/deals/eligible/summary`)
await assertResponseStatus(res, 200)
assert.strictEqual(res.headers.get('cache-control'), 'max-age=21600')
const body = await res.json()
assert.deepStrictEqual(body, {
allocatorId: 'f0500',
dealCount: 6,
clients: [
{ clientId: 'f0800', dealCount: 4 },
{ clientId: 'f0810', dealCount: 2 }
]
})
})

it('returns an empty array for miners with no deals in our DB', async () => {
const res = await fetch(`${spark}/allocator/f0000/deals/eligible/summary`)
await assertResponseStatus(res, 200)
assert.strictEqual(res.headers.get('cache-control'), 'max-age=21600')
const body = await res.json()
assert.deepStrictEqual(body, {
allocatorId: 'f0000',
dealCount: 0,
clients: []
})
})
})
})
})

0 comments on commit 3839c69

Please sign in to comment.