Skip to content

Commit

Permalink
Merge pull request #38 from hirosystems/develop
Browse files Browse the repository at this point in the history
release to beta
  • Loading branch information
rafaelcr authored Jul 29, 2024
2 parents 8a8e257 + 4485057 commit a4181f7
Show file tree
Hide file tree
Showing 27 changed files with 1,487 additions and 239 deletions.
2 changes: 0 additions & 2 deletions .cargo/config

This file was deleted.

6 changes: 6 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[alias]
runehook-install = "install --path . --locked --force"

[env]
# Run tests in one thread so we can support postgres migrations correctly.
RUST_TEST_THREADS = "1"
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ jobs:
docker-compose -f docker/docker-compose.dev.postgres.yml up -d
docker-compose -f docker/docker-compose.dev.postgres.yml logs -t -f --no-color &> docker-compose-logs.txt &
- name: Cargo test
- name: Update Rust
run: |
rustup update
RUST_BACKTRACE=1 cargo test --all -- --test-threads=1
- name: Run tests
run: |
cargo install --force cargo-tarpaulin
cargo tarpaulin --out lcov -- --test-threads=1
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
Expand Down
23 changes: 22 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@
"TS_NODE_SKIP_IGNORE": "true"
},
"killBehavior": "polite"
}
},
{
"type": "node",
"request": "launch",
"name": "Jest",
"program": "${workspaceFolder}/api/node_modules/jest/bin/jest",
"cwd": "${workspaceFolder}/api/",
"args": [
"--testTimeout=3600000",
"--runInBand",
"--no-cache",
],
"outputCapture": "std",
"console": "integratedTerminal",
"preLaunchTask": "npm: testenv:run",
"postDebugTask": "npm: testenv:stop",
"env": {
"PGHOST": "localhost",
"PGUSER": "postgres",
"PGPASSWORD": "postgres",
},
},
]
}
43 changes: 43 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "npm: testenv:run",
"type": "shell",
"command": "npm run testenv:run -- -d",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/api/",
},
"problemMatcher": {
"pattern": {
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
},
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "."
}
}
},
{
"label": "npm: testenv:stop",
"type": "shell",
"command": "npm run testenv:stop",
"options": {
"cwd": "${workspaceFolder}/api/",
},
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
}
}
]
}
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tokio-postgres = "0.7.10"
tokio = { version = "1.38.0", features = ["rt-multi-thread", "macros"] }
refinery = { version = "0.8", features = ["tokio-postgres"] }
num-traits = "0.2.14"
maplit = "1.0.2"

[dev-dependencies]
test-case = "3.1.0"
Expand Down
5 changes: 4 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
"generate:vercel": "npm run generate:git-info && npm run generate:openapi && npm run generate:docs",
"lint:eslint": "eslint . --ext .ts,.tsx -f unix",
"lint:prettier": "prettier --check src/**/*.ts tests/**/*.ts",
"lint:unused-exports": "ts-unused-exports tsconfig.json --showLineNumber --excludePathsFromReport=util/*"
"lint:unused-exports": "ts-unused-exports tsconfig.json --showLineNumber --excludePathsFromReport=util/*",
"testenv:run": "docker-compose -f ../docker/docker-compose.dev.postgres.yml up",
"testenv:stop": "docker-compose -f ../docker/docker-compose.dev.postgres.yml down -v -t 0",
"testenv:logs": "docker-compose -f ../docker/docker-compose.dev.postgres.yml logs -t -f"
},
"author": "Hiro Systems PBC <[email protected]> (https://hiro.so)",
"license": "Apache 2.0",
Expand Down
5 changes: 4 additions & 1 deletion api/src/api/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ const RuneNumberSchema = Type.RegEx(/^[0-9]+$/, { title: 'Rune number' });
export const RuneNumberSchemaCType = TypeCompiler.Compile(RuneNumberSchema);
const RuneNameSchema = Type.RegEx(/^[A-Z]+$/, { title: 'Rune name' });
export const RuneNameSchemaCType = TypeCompiler.Compile(RuneNameSchema);
const RuneSpacedNameSchema = Type.RegEx(/^[A-Z](•[A-Z]+)+$/, { title: 'Rune name with spacers' });
const RuneSpacedNameSchema = Type.RegEx(/^[A-Za-z]+(•[A-Za-z]+)+$/, {
title: 'Rune name with spacers',
});
export const RuneSpacedNameSchemaCType = TypeCompiler.Compile(RuneSpacedNameSchema);

export const RuneSchema = Type.Union([
Expand Down Expand Up @@ -306,6 +308,7 @@ const RuneDetailResponseSchema = Type.Object({
rune: Type.Object(
{
id: RuneIdResponseSchema,
number: RuneNumberResponseSchema,
name: RuneNameResponseSchema,
spaced_name: RuneSpacedNameResponseSchema,
},
Expand Down
3 changes: 3 additions & 0 deletions api/src/api/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function parseEtchingResponse(rune: DbRuneWithChainTip): EtchingResponse
const total_burns = rune.total_burns == null ? '0' : rune.total_burns;
if (
rune.terms_amount == null ||
rune.cenotaph ||
(rune.terms_cap && BigNumber(total_mints).gte(rune.terms_cap)) ||
(rune.terms_height_start && BigNumber(rune.chain_tip).lt(rune.terms_height_start)) ||
(rune.terms_height_end && BigNumber(rune.chain_tip).gt(rune.terms_height_end)) ||
Expand Down Expand Up @@ -67,6 +68,7 @@ export function parseActivityResponse(entry: DbItemWithRune<DbLedgerEntry>): Act
return {
rune: {
id: entry.rune_id,
number: entry.number,
name: entry.name,
spaced_name: entry.spaced_name,
},
Expand All @@ -90,6 +92,7 @@ export function parseBalanceResponse(item: DbItemWithRune<DbBalance>): BalanceRe
return {
rune: {
id: item.rune_id,
number: item.number,

Check warning on line 95 in api/src/api/util/helpers.ts

View check run for this annotation

Codecov / codecov/patch

api/src/api/util/helpers.ts#L95

Added line #L95 was not covered by tests
name: item.name,
spaced_name: item.spaced_name,
},
Expand Down
8 changes: 4 additions & 4 deletions api/src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export class PgStore extends BasePgStore {
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbLedgerEntry>>[]>`
WITH ${cte ? cte : this.sql`none AS (SELECT NULL)`},
results AS (
SELECT l.*, r.name, r.spaced_name, r.divisibility, ${count} AS total
SELECT l.*, r.name, r.number, r.spaced_name, r.divisibility, ${count} AS total
FROM ledger AS l
INNER JOIN runes AS r ON r.id = l.rune_id
WHERE ${filter}
Expand Down Expand Up @@ -222,7 +222,7 @@ export class PgStore extends BasePgStore {
): Promise<DbPaginatedResult<DbItemWithRune<DbBalance>>> {
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbBalance>>[]>`
WITH grouped AS (
SELECT DISTINCT ON (b.address) b.address, b.balance, b.total_operations, b.rune_id, r.name,
SELECT DISTINCT ON (b.address) b.address, b.balance, b.total_operations, b.rune_id, r.name, r.number
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
FROM balance_changes AS b
INNER JOIN runes AS r ON r.id = b.rune_id
Expand All @@ -245,7 +245,7 @@ export class PgStore extends BasePgStore {
): Promise<DbItemWithRune<DbBalance> | undefined> {
const results = await this.sql<DbItemWithRune<DbBalance>[]>`
SELECT b.rune_id, b.address, b.balance, b.total_operations, r.name,
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
r.number, r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
FROM balance_changes AS b

Check warning on line 249 in api/src/pg/pg-store.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/pg-store.ts#L247-L249

Added lines #L247 - L249 were not covered by tests
INNER JOIN runes AS r ON r.id = b.rune_id
WHERE ${runeFilter(this.sql, id, 'r')} AND address = ${address}
Expand All @@ -263,7 +263,7 @@ export class PgStore extends BasePgStore {
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbBalance>>[]>`
WITH grouped AS (
SELECT DISTINCT ON (b.rune_id) b.address, b.balance, b.total_operations, b.rune_id, r.name,
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
r.number, r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
FROM balance_changes AS b
INNER JOIN runes AS r ON r.id = b.rune_id
WHERE address = ${address}
Expand Down
4 changes: 3 additions & 1 deletion api/src/pg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type DbPaginatedResult<T> = {

export type DbCountedQueryResult<T> = T & { total: number };

type DbRune = {
export type DbRune = {

Check warning on line 8 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L8

Added line #L8 was not covered by tests
id: string;
number: number;
name: string;
Expand All @@ -17,6 +17,7 @@ type DbRune = {
divisibility: number;
premine: string;
symbol: string;
cenotaph: boolean;

Check warning on line 20 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L20

Added line #L20 was not covered by tests
terms_amount: string | null;
terms_cap: string | null;
terms_height_start: string | null;
Expand Down Expand Up @@ -52,6 +53,7 @@ export type DbLedgerEntry = {

export type DbItemWithRune<T> = T & {
name: string;
number: number;

Check warning on line 56 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L56

Added line #L56 was not covered by tests
spaced_name: string;
divisibility: number;
total_operations: number;
Expand Down
152 changes: 150 additions & 2 deletions api/tests/api/api.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,151 @@
test('sample', () => {
expect(true);
import { ENV } from '../../src/env';
import { PgStore } from '../../src/pg/pg-store';
import {
dropDatabase,
insertDbLedgerEntry,
insertRune,
sampleRune,
runMigrations,
startTestApiServer,
TestFastifyServer,
insertSupplyChange,
sampleLedgerEntry,
} from '../helpers';

describe('Endpoints', () => {
let db: PgStore;
let fastify: TestFastifyServer;

const rune = sampleRune('1:1', 'Sample Rune');
const ledgerEntry = sampleLedgerEntry(rune.id);

beforeEach(async () => {
ENV.PGDATABASE = 'postgres';
db = await PgStore.connect();
fastify = await startTestApiServer(db);
await runMigrations(db);
await insertRune(db, rune);
const event_index = 0;
await insertDbLedgerEntry(db, ledgerEntry, event_index);
await insertSupplyChange(db, rune.id, 1);
});

afterEach(async () => {
if (fastify) {
await fastify.close();
}

await dropDatabase(db);
await db.close();
});

describe('Etchings', () => {
test('lists runes', async () => {
const expected = {
divisibility: 0,
id: '1:1',
location: {
block_hash: '0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5',
block_height: 840000,
timestamp: 0,
tx_id: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e',
tx_index: 1,
},
mint_terms: {
amount: '100',
cap: '5000000',
height_end: null,
height_start: null,
offset_end: null,
offset_start: null,
},
name: 'Sample Rune',
number: 1,
spaced_name: 'Sample•Rune',
supply: {
burned: '0',
current: '0',
mint_percentage: '0.0000',
mintable: false,
minted: '0',
premine: '0',
total_burns: '0',
total_mints: '0',
},
symbol: 'ᚠ',
turbo: false,
};
const runesResponse = await fastify.inject({
method: 'GET',
url: '/runes/v1/etchings',
});
expect(runesResponse.statusCode).toBe(200);
expect(runesResponse.json().results).not.toHaveLength(0);

const response = await fastify.inject({
method: 'GET',
url: '/runes/v1/etchings/' + ledgerEntry.rune_id,
});
expect(response.statusCode).toBe(200);
expect(response.json()).toStrictEqual(expected);
});

test('can fetch by spaced name', async () => {
const url = '/runes/v1/etchings/' + rune.spaced_name;
const response = await fastify.inject({
method: 'GET',
url: url,
});
expect(response.statusCode).toBe(200);
expect(response.json().spaced_name).toEqual(rune.spaced_name);
});

test('can not fetch by spaced name if lacking bullets', async () => {
const url = '/runes/v1/etchings/' + rune.spaced_name.replaceAll('•', '-');
const response = await fastify.inject({
method: 'GET',
url: url,
});
expect(response.statusCode).toBe(400);
});
});
describe('Transactions', () => {
test('shows details', async () => {
const expected = {
limit: 20,
offset: 0,
results: [
{
address: '0',
amount: '0',
location: {
block_hash: '0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5',
block_height: 840000,
output: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e:0',
timestamp: 0,
tx_id: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e',
tx_index: 0,
vout: 0,
},
operation: 'etching',
receiver_address: '0',
rune: {
id: '1:1',
name: 'Sample Rune',
number: 1,
spaced_name: 'Sample•Rune',
},
},
],
total: 1,
};
const txid = ledgerEntry.tx_id;
const response = await fastify.inject({
method: 'GET',
url: '/runes/v1/transactions/' + txid + '/activity',
});
expect(response.statusCode).toBe(200);
expect(response.json()).toStrictEqual(expected);
});
});
});
Loading

0 comments on commit a4181f7

Please sign in to comment.