Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

chore: initial release of arns-resolver #3

Merged
merged 22 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8740e59
chore(docs): update license headers and package.json
Mar 21, 2024
d827090
feat(kv): introduce KVBufferStore interface and implement it with lmdb
Mar 21, 2024
ac7698b
Merge pull request #1 from ar-io/arns-cache
dtfiedler Mar 21, 2024
ee79b87
feat(records): implement logic using ar.io/sdk
Mar 22, 2024
c8e03fc
chore(comment): fix lint error and add comment
Mar 22, 2024
c865cc4
fix(records): avoid setting records with invalid contarctTxIds in the…
Mar 22, 2024
e04e68c
fix(cache): optimize cache inserts, update info api
Mar 22, 2024
977bf01
feat(ttl): add ttl seconds to lmdb cache as optional configuration
Mar 22, 2024
06a64b4
fix(ttl): properly set ttl as bigint to have consistent byte count
Mar 22, 2024
90a88a4
chore: remove lingering console.log
Mar 22, 2024
ceca751
chore(jest): setup jest and add test for lmdbkvstore
Mar 22, 2024
0bbee63
fix(ant): support legacy ant format with default TTL
Mar 22, 2024
bc6b421
feat(pLimit): add p-limit to limit concurrency of requests and better…
Mar 22, 2024
09eea37
chore(package.json): set p-limit to 4.0.0
Mar 22, 2024
f1083ac
chore: remove TODOs and update comments
Mar 22, 2024
2441f0c
Merge pull request #2 from ar-io/PE-5830-cache-record-resolution
dtfiedler Mar 22, 2024
7f65171
chore(github): pubish amd images to ghcr
Mar 22, 2024
792ef93
chore(logs): add debug logs for traceability
Mar 22, 2024
319da0b
fix(cache): use a nullish coalescing operator on transactionId check
Mar 23, 2024
a79a0bf
chore(arm): support ARM build images
Apr 1, 2024
fe3da64
chore(arm): push arm build image to ghcr
Apr 1, 2024
f90dc9f
chore(github): fix platforms array
Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,40 @@ jobs:
- run: yarn
- run: yarn ${{ matrix.step }}

# push:
# needs: [build]
# if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main'
# runs-on: ubuntu-latest
# permissions:
# id-token: write
# contents: read
# checks: write
# packages: write
# steps:
# - uses: actions/checkout@v3
push:
needs: [build]
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
checks: write
packages: write
steps:
- uses: actions/checkout@v3

# - name: Set up QEMU
# uses: docker/setup-qemu-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2

# - name: Setup Docker buildx
# uses: docker/setup-buildx-action@v2
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2

# - name: Log in to the GitHub Container Registry
# uses: docker/login-action@v1
# with:
# registry: ghcr.io
# username: ${{ github.actor }}
# password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to the GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# - name: Build and push container image to GitHub Container Registry
# uses: docker/build-push-action@v4
# with:
# push: true
# platforms: linux/amd64,linux/arm64
# # TODO: add build version node args
# tags: |
# ghcr.io/ar-io/arns-resolver:${{ github.sha }}
# ghcr.io/ar-io/arns-resolver:latest
- name: Build and push container image to GitHub Container Registry
uses: docker/build-push-action@v4
with:
push: true
platforms: linux/amd64,linux/arm64
# TODO: add build version node args
tags: |
ghcr.io/ar-io/arns-resolver:${{ github.sha }}
ghcr.io/ar-io/arns-resolver:latest

# deploy:
# if: github.ref == 'refs/heads/main'
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
data
node_modules
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,20 @@ Requirements:
Starting the service:

- `nvm use`
- `yarn start:watch`
- `yarn start:watch`

You can check the service is running by running the command:

```shell
curl localhost:5000/ar-io/observer/healthcheck
curl localhost:6000/ar-io/resolver/healthcheck
{"uptime":2.555423702,"date":"2023-09-14T21:24:27.677Z","message":"Welcome to the Permaweb."}
```


### Docker

Build and run the container:

```shell
docker build --build-arg NODE_VERSION=$(cat .nvmrc |cut -c2-8) --build-arg NODE_VERSION_SHORT=$(cat .nvmrc |cut -c2-3) . -t arns-resolver
docker run -p 5000:5000 arns-resolver
docker run -p 6000:6000 arns-resolver
```
57 changes: 44 additions & 13 deletions docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,35 @@ components:
nullable: true
Timestamp:
type: integer
nullable: true
Evaluation:
type: boolean
HealthCheck:
type: object
properties:
uptime: { type: number }
date: {
type: string,
format: date
}
message: { type: string }
type: object
properties:
uptime: { type: number }
date: { type: string, format: date }
message: { type: string }
URL:
type: string
description: |
A URL to a resource
Info:
type: object
properties:
cacheUrl: { '$ref': '#/components/schemas/URL' }
contractTxId: { '$ref': '#/components/schemas/ArweaveId' }
type: object
properties:
cacheUrl: { '$ref': '#/components/schemas/URL' }
contractTxId: { '$ref': '#/components/schemas/ArweaveId' }
lastEvaluationTimestamp: { '$ref': '#/components/schemas/Timestamp' }
Record:
type: object
properties:
name: { type: string }
ttlSeconds: { type: integer }
txId: { $ref: '#/components/schemas/ArweaveId' }
endTimestamp: { '$ref': '#/components/schemas/Timestamp' }
owner: { $ref: '#/components/schemas/ArweaveAddress' }
contractTxId: { $ref: '#/components/schemas/ArweaveId' }
type: { type: string }

paths:
'/ar-io/resolver/healthcheck':
Expand All @@ -59,9 +68,31 @@ paths:
application/json:
schema:
'$ref': '#/components/schemas/Info'
'/ar-io/resolver/record/{name}':
'/ar-io/resolver/records/{name}':
get:
responses:
'200':
description: |-
200 response
content:
application/json:
schema:
'$ref': '#/components/schemas/Record'
'404':
description: |-
404 response
content:
application/json:
schema:
type: object
properties:
message: { type: string }
'500':
description: |-
500 response
content:
application/json:
schema:
type: object
properties:
error: { type: string }
17 changes: 17 additions & 0 deletions jest.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"preset": "ts-jest",
"testEnvironment": "node",
"extensionsToTreatAsEsm": [".ts"],
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.js$": "$1"
},
"transform": {
"^.+\\.m?[tj]sx?$": [
"ts-jest",
{
"useESM": true
}
]
},
"moduleFileExtensions": ["ts", "js", "json", "node"]
}
16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
{
"name": "ar-io-node",
"version": "0.0.1",
"description": "The AR.IO network observer.",
"description": "The AR.IO ArNS resolver.",
"license": "AGPL-3.0-or-later",
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/ar-io/ar-io-observer"
"url": "https://github.com/ar-io/arns-resolver"
},
"dependencies": {
"@ar.io/sdk": "^1.0.0-alpha.9",
"@ardrive/ardrive-promise-cache": "^1.1.4",
"@ar.io/sdk": "^1.0.0-alpha.12",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-async-handler": "^1.2.0",
"express-openapi-validator": "^5.0.5",
"express-prometheus-middleware": "^1.2.0",
"lmdb": "^3.0.0",
"middleware-async": "^1.3.5",
"p-limit": "^4.0.0",
"prom-client": "^14.0.1",
"swagger-ui-express": "^5.0.0",
"winston": "^3.7.2",
Expand All @@ -29,6 +30,7 @@
"@types/cors": "^2.8.16",
"@types/express": "^4.17.17",
"@types/express-prometheus-middleware": "^1.2.1",
"@types/jest": "^29.5.12",
"@types/node": "^16.11.7",
"@types/swagger-ui-express": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^5.26.0",
Expand All @@ -40,9 +42,11 @@
"eslint-plugin-mocha": "^10.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-unicorn": "^45.0.2",
"jest": "^29.7.0",
"nodemon": "^3.1.0",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.3.0"
},
Expand All @@ -52,6 +56,8 @@
"start": "node dist/service.js",
"clean": "npx rimraf [ coverage dist cache ]",
"lint:check": "eslint src",
"lint:fix": "eslint --fix src"
"lint:fix": "eslint --fix src",
"format:check": "prettier --check .",
"format:fix": "prettier --write ."
}
}
2 changes: 1 addition & 1 deletion resources/license.header.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* AR.IO Observer
* AR.IO ArNS Resolver
* Copyright (C) 2023 Permanent Data Solutions, Inc. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
Expand Down
38 changes: 38 additions & 0 deletions src/cache/lmdb-kv-store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* AR.IO ArNS Resolver
* Copyright (C) 2023 Permanent Data Solutions, Inc. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { LmdbKVStore } from './lmdb-kv-store.js';

describe('LmdbKVStore', () => {
const cache = new LmdbKVStore({
dbPath: './data/test',
ttlSeconds: 1,
});

it('should set and get value', async () => {
await cache.set('test', Buffer.from('hello'));
const value = await cache.get('test');
expect(value).toEqual(Buffer.from('hello'));
});

it('should remove a value once ttl has expired', async () => {
await cache.set('expire', Buffer.from('hello'));
await new Promise((resolve) => setTimeout(resolve, 1000));
const value = await cache.get('expire');
expect(value).toBeUndefined();
});
});
Loading
Loading