mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo-indexer.git
synced 2026-09-21 16:52:02 -07:00
Adding block height to all models
This commit is contained in:
+37
-3
@@ -86,12 +86,13 @@ All routes are under `/level` with a consistent CRUD pattern generated from `ENT
|
|||||||
| Method | Path | Query params |
|
| Method | Path | Query params |
|
||||||
|--------|------|----------------|
|
|--------|------|----------------|
|
||||||
| `GET` | `/profile/recent` | `limit` (default 100, max 100), `offset` (default 0) |
|
| `GET` | `/profile/recent` | `limit` (default 100, max 100), `offset` (default 0) |
|
||||||
|
| `GET` | `/posts/recent` | `limit` (default 100, max 100), `offset` (default 0) |
|
||||||
|
|
||||||
Returns profiles sorted by **block height** (newest first), using each profile’s `txid` to look up `blockHeight` in `ptxs`. Tie-breaker: `seen` timestamp descending.
|
Returns profiles or posts sorted by **block height** (newest first), using the `blockHeight` field stored on each entity document at indexing time. Tie-breaker: `seen` timestamp descending.
|
||||||
|
|
||||||
The `seen` field is **Unix epoch milliseconds** from the block header time (`block.time * 1000` at indexing time).
|
The `seen` field is **Unix epoch milliseconds** from the block header time (`block.time * 1000` at indexing time).
|
||||||
|
|
||||||
Response shape:
|
Response shape (`/profile/recent`):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -108,7 +109,24 @@ Response shape:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Implementation: `profile-query` adapter (LevelDB scan) → `list-recent-profiles` use case → `/profile` REST controller.
|
Response shape (`/posts/recent`):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"txid": "...",
|
||||||
|
"addr": "bitcoincash:q...",
|
||||||
|
"text": "...",
|
||||||
|
"seen": 1500000000000,
|
||||||
|
"blockHeight": 600000
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "limit": 100, "offset": 0, "total": 42, "hasMore": false }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Implementation: `profile-query` / `post-query` adapter (LevelDB scan) → `list-recent-profiles` / `list-recent-posts` use case → REST controller.
|
||||||
|
|
||||||
**Tradeoff:** Full scan of `profiles` on each request; suitable for moderate corpus sizes. A height-indexed store would be needed for very large archives.
|
**Tradeoff:** Full scan of `profiles` on each request; suitable for moderate corpus sizes. A height-indexed store would be needed for very large archives.
|
||||||
|
|
||||||
@@ -157,6 +175,22 @@ createEntityDb('post', 'txid', 'postData')
|
|||||||
|
|
||||||
**Not normalized like SQL.** LevelDB stores are document keyed for fast lookup by txid or address, similar to the Go `db/item/memo` objects but without sharding.
|
**Not normalized like SQL.** LevelDB stores are document keyed for fast lookup by txid or address, similar to the Go `db/item/memo` objects but without sharding.
|
||||||
|
|
||||||
|
**Denormalized block height.** Every entity written by the indexer includes a `blockHeight` field (the block in which the memo transaction was confirmed, or `tip + 1` for unconfirmed txs). This avoids ptx lookups when serving `/recent` query routes. The `ptxs` store remains for idempotency only.
|
||||||
|
|
||||||
|
Common fields on indexed documents:
|
||||||
|
|
||||||
|
| Entity | Key | Stored fields (includes) |
|
||||||
|
|--------|-----|--------------------------|
|
||||||
|
| post | txid | `addr`, `text`, `seen`, `blockHeight` |
|
||||||
|
| profile | addr | `text`, `txid`, `seen`, `addr`, `blockHeight` |
|
||||||
|
| name | addr | `name`, `txid`, `seen`, `addr`, `blockHeight` |
|
||||||
|
| profilePic | addr | `url`, `txid`, `seen`, `addr`, `blockHeight` |
|
||||||
|
| like | txid | `addr`, `postTxid`, `seen`, `tip`, `blockHeight` |
|
||||||
|
| follow | composite key | `followerAddr`, `followeePkHash`, `unfollow`, `txid`, `seen`, `blockHeight` |
|
||||||
|
| postParent / postChild | txid | `parentTxid`, `childTxid`, `blockHeight` |
|
||||||
|
| room | composite key | `room`, `txid`, `seen`, `type`, `blockHeight` (+ `addr` for follows) |
|
||||||
|
| processError | txid | `error`, `ts`, `blockHeight` |
|
||||||
|
|
||||||
**No secondary indexes in v1.** Queries like “all posts by address” may require scanning or a future `memo-query` adapter—out of scope for the indexer write path.
|
**No secondary indexes in v1.** Queries like “all posts by address” may require scanning or a future `memo-query` adapter—out of scope for the indexer write path.
|
||||||
|
|
||||||
**JSON values** keep debugging simple; binary serialization would save space but break parity with psf-slp-db tooling.
|
**JSON values** keep debugging simple; binary serialization would save space but break parity with psf-slp-db tooling.
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ import { logProcessError } from './helpers.js'
|
|||||||
import { PK_HASH_LENGTH, PREFIX_UNFOLLOW } from '../../lib/memo-codes.js'
|
import { PK_HASH_LENGTH, PREFIX_UNFOLLOW } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleFollow (ctx) {
|
export async function handleFollow (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const { pushDatas, prefix } = decoded
|
const { pushDatas, prefix } = decoded
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid follow push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid follow push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushDatas[1].length !== PK_HASH_LENGTH) {
|
if (pushDatas[1].length !== PK_HASH_LENGTH) {
|
||||||
await logProcessError(adapters, txid, 'follow pk hash wrong size')
|
await logProcessError(adapters, txid, 'follow pk hash wrong size', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ export async function handleFollow (ctx) {
|
|||||||
followeePkHash,
|
followeePkHash,
|
||||||
unfollow,
|
unfollow,
|
||||||
txid,
|
txid,
|
||||||
seen
|
seen,
|
||||||
|
blockHeight
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
import { isMemoPrefix } from '../../lib/memo-codes.js'
|
import { isMemoPrefix } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function logProcessError (adapters, txid, error) {
|
export async function logProcessError (adapters, txid, error, blockHeight) {
|
||||||
try {
|
try {
|
||||||
await adapters.processErrorDb.create(txid, { error, ts: Date.now() })
|
await adapters.processErrorDb.create(txid, { error, ts: Date.now(), blockHeight })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to log process error:', err.message)
|
console.error('Failed to log process error:', err.message)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ import { txHashFromPush, logProcessError } from './helpers.js'
|
|||||||
import { TX_HASH_LENGTH } from '../../lib/memo-codes.js'
|
import { TX_HASH_LENGTH } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleLike (ctx) {
|
export async function handleLike (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen, txDetails } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, txDetails, blockHeight } = ctx
|
||||||
const { pushDatas } = decoded
|
const { pushDatas } = decoded
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid like push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid like push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushDatas[1].length !== TX_HASH_LENGTH) {
|
if (pushDatas[1].length !== TX_HASH_LENGTH) {
|
||||||
await logProcessError(adapters, txid, 'like post tx hash wrong size')
|
await logProcessError(adapters, txid, 'like post tx hash wrong size', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,8 @@ export async function handleLike (ctx) {
|
|||||||
addr: signerAddr,
|
addr: signerAddr,
|
||||||
postTxid,
|
postTxid,
|
||||||
seen,
|
seen,
|
||||||
tip
|
tip,
|
||||||
|
blockHeight
|
||||||
}
|
}
|
||||||
await adapters.likeDb.create(txid, likeData)
|
await adapters.likeDb.create(txid, likeData)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,25 @@ import { utf8FromPush, logProcessError, normalizeTwoPushMemoDatas } from './help
|
|||||||
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handlePost (ctx) {
|
export async function handlePost (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid post push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid post push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = utf8FromPush(pushDatas[1])
|
const text = utf8FromPush(pushDatas[1])
|
||||||
if (!text.length) {
|
if (!text.length) {
|
||||||
await logProcessError(adapters, txid, 'empty post')
|
await logProcessError(adapters, txid, 'empty post', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (text.length > MAX_POST_SIZE) {
|
if (text.length > MAX_POST_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'post too large')
|
await logProcessError(adapters, txid, 'post too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const postData = { addr: signerAddr, text, seen }
|
const postData = { addr: signerAddr, text, seen, blockHeight }
|
||||||
try {
|
try {
|
||||||
await adapters.postDb.get(txid)
|
await adapters.postDb.get(txid)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -3,28 +3,28 @@ import { MAX_REPLY_SIZE } from '../../lib/memo-codes.js'
|
|||||||
import { handlePost } from './post.js'
|
import { handlePost } from './post.js'
|
||||||
|
|
||||||
export async function handleReply (ctx) {
|
export async function handleReply (ctx) {
|
||||||
const { adapters, txid, decoded } = ctx
|
const { adapters, txid, decoded, blockHeight } = ctx
|
||||||
const { pushDatas } = decoded
|
const { pushDatas } = decoded
|
||||||
|
|
||||||
if (pushDatas.length !== 3) {
|
if (pushDatas.length !== 3) {
|
||||||
await logProcessError(adapters, txid, `invalid reply push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid reply push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentTxid = txHashFromPush(pushDatas[1])
|
const parentTxid = txHashFromPush(pushDatas[1])
|
||||||
if (!parentTxid) {
|
if (!parentTxid) {
|
||||||
await logProcessError(adapters, txid, 'invalid parent tx hash for reply')
|
await logProcessError(adapters, txid, 'invalid parent tx hash for reply', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = utf8FromPush(pushDatas[2])
|
const text = utf8FromPush(pushDatas[2])
|
||||||
if (text.length > MAX_REPLY_SIZE) {
|
if (text.length > MAX_REPLY_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'reply too large')
|
await logProcessError(adapters, txid, 'reply too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await adapters.postParentDb.create(txid, { parentTxid, childTxid: txid })
|
await adapters.postParentDb.create(txid, { parentTxid, childTxid: txid, blockHeight })
|
||||||
await adapters.postChildDb.create(parentTxid, { parentTxid, childTxid: txid })
|
await adapters.postChildDb.create(parentTxid, { parentTxid, childTxid: txid, blockHeight })
|
||||||
|
|
||||||
await handlePost({ ...ctx, decoded: { ...decoded, pushDatas: [pushDatas[0], pushDatas[2]] } })
|
await handlePost({ ...ctx, decoded: { ...decoded, pushDatas: [pushDatas[0], pushDatas[2]] } })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import { utf8FromPush, logProcessError, normalizeTwoPushMemoDatas } from './help
|
|||||||
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleSetName (ctx) {
|
export async function handleSetName (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid set name push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid set name push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = utf8FromPush(pushDatas[1])
|
const name = utf8FromPush(pushDatas[1])
|
||||||
if (name.length > MAX_POST_SIZE) {
|
if (name.length > MAX_POST_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'set name too large')
|
await logProcessError(adapters, txid, 'set name too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await adapters.nameDb.create(signerAddr, { name, txid, seen, addr: signerAddr })
|
await adapters.nameDb.create(signerAddr, { name, txid, seen, addr: signerAddr, blockHeight })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,23 @@ import { utf8FromPush, logProcessError, normalizeTwoPushMemoDatas } from './help
|
|||||||
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleSetProfilePic (ctx) {
|
export async function handleSetProfilePic (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid profile pic push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid profile pic push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = utf8FromPush(pushDatas[1])
|
const url = utf8FromPush(pushDatas[1])
|
||||||
if (!url.length) {
|
if (!url.length) {
|
||||||
await logProcessError(adapters, txid, 'empty profile pic url')
|
await logProcessError(adapters, txid, 'empty profile pic url', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (url.length > MAX_POST_SIZE) {
|
if (url.length > MAX_POST_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'profile pic url too large')
|
await logProcessError(adapters, txid, 'profile pic url too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await adapters.profilePicDb.create(signerAddr, { url, txid, seen, addr: signerAddr })
|
await adapters.profilePicDb.create(signerAddr, { url, txid, seen, addr: signerAddr, blockHeight })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import { utf8FromPush, logProcessError, normalizeTwoPushMemoDatas } from './help
|
|||||||
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleSetProfile (ctx) {
|
export async function handleSetProfile (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
const pushDatas = normalizeTwoPushMemoDatas(decoded.pushDatas)
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid profile push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid profile push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = utf8FromPush(pushDatas[1])
|
const text = utf8FromPush(pushDatas[1])
|
||||||
if (text.length > MAX_POST_SIZE) {
|
if (text.length > MAX_POST_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'profile too large')
|
await logProcessError(adapters, txid, 'profile too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await adapters.profileDb.create(signerAddr, { text, txid, seen, addr: signerAddr })
|
await adapters.profileDb.create(signerAddr, { text, txid, seen, addr: signerAddr, blockHeight })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { utf8FromPush, logProcessError, roomKey } from './helpers.js'
|
|||||||
import { PREFIX_TOPIC_UNFOLLOW } from '../../lib/memo-codes.js'
|
import { PREFIX_TOPIC_UNFOLLOW } from '../../lib/memo-codes.js'
|
||||||
|
|
||||||
export async function handleTopicFollow (ctx) {
|
export async function handleTopicFollow (ctx) {
|
||||||
const { adapters, txid, signerAddr, decoded, seen } = ctx
|
const { adapters, txid, signerAddr, decoded, seen, blockHeight } = ctx
|
||||||
const { pushDatas, prefix } = decoded
|
const { pushDatas, prefix } = decoded
|
||||||
|
|
||||||
if (pushDatas.length !== 2) {
|
if (pushDatas.length !== 2) {
|
||||||
await logProcessError(adapters, txid, `invalid topic follow push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid topic follow push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ export async function handleTopicFollow (ctx) {
|
|||||||
unfollow,
|
unfollow,
|
||||||
txid,
|
txid,
|
||||||
seen,
|
seen,
|
||||||
type: 'follow'
|
type: 'follow',
|
||||||
|
blockHeight
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import { MAX_POST_SIZE } from '../../lib/memo-codes.js'
|
|||||||
import { handlePost } from './post.js'
|
import { handlePost } from './post.js'
|
||||||
|
|
||||||
export async function handleTopicMessage (ctx) {
|
export async function handleTopicMessage (ctx) {
|
||||||
const { adapters, txid, decoded, seen } = ctx
|
const { adapters, txid, decoded, seen, blockHeight } = ctx
|
||||||
const { pushDatas } = decoded
|
const { pushDatas } = decoded
|
||||||
|
|
||||||
if (pushDatas.length !== 3) {
|
if (pushDatas.length !== 3) {
|
||||||
await logProcessError(adapters, txid, `invalid topic message push data count ${pushDatas.length}`)
|
await logProcessError(adapters, txid, `invalid topic message push data count ${pushDatas.length}`, blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const room = utf8FromPush(pushDatas[1])
|
const room = utf8FromPush(pushDatas[1])
|
||||||
const message = utf8FromPush(pushDatas[2])
|
const message = utf8FromPush(pushDatas[2])
|
||||||
if ((room.length + message.length) > MAX_POST_SIZE) {
|
if ((room.length + message.length) > MAX_POST_SIZE) {
|
||||||
await logProcessError(adapters, txid, 'topic message too large')
|
await logProcessError(adapters, txid, 'topic message too large', blockHeight)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,5 +23,5 @@ export async function handleTopicMessage (ctx) {
|
|||||||
decoded: { ...decoded, pushDatas: [pushDatas[0], pushDatas[2]] }
|
decoded: { ...decoded, pushDatas: [pushDatas[0], pushDatas[2]] }
|
||||||
})
|
})
|
||||||
|
|
||||||
await adapters.roomDb.create(roomKey(room, txid), { room, txid, seen, type: 'post' })
|
await adapters.roomDb.create(roomKey(room, txid), { room, txid, seen, type: 'post', blockHeight })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { assert } from 'chai'
|
import { assert } from 'chai'
|
||||||
|
import sinon from 'sinon'
|
||||||
import {
|
import {
|
||||||
normalizeTwoPushMemoDatas,
|
normalizeTwoPushMemoDatas,
|
||||||
stripLeadingEmptyPushes
|
stripLeadingEmptyPushes,
|
||||||
|
logProcessError
|
||||||
} from '../../../../src/use-cases/action-types/helpers.js'
|
} from '../../../../src/use-cases/action-types/helpers.js'
|
||||||
import { PREFIX_SET_PROFILE_PIC, PREFIX_POST } from '../../../../src/lib/memo-codes.js'
|
import { PREFIX_SET_PROFILE_PIC, PREFIX_POST } from '../../../../src/lib/memo-codes.js'
|
||||||
|
|
||||||
@@ -52,4 +54,18 @@ describe('#action-types/helpers', () => {
|
|||||||
assert.deepEqual(result[0], payload)
|
assert.deepEqual(result[0], payload)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('#logProcessError', () => {
|
||||||
|
it('should store blockHeight on process error records', async () => {
|
||||||
|
const create = sinon.stub().resolves()
|
||||||
|
const adapters = { processErrorDb: { create } }
|
||||||
|
|
||||||
|
await logProcessError(adapters, 'tx1', 'bad data', 600100)
|
||||||
|
|
||||||
|
assert.equal(create.callCount, 1)
|
||||||
|
assert.equal(create.firstCall.args[0], 'tx1')
|
||||||
|
assert.equal(create.firstCall.args[1].error, 'bad data')
|
||||||
|
assert.equal(create.firstCall.args[1].blockHeight, 600100)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ describe('#handlePost', () => {
|
|||||||
txid: 'abc123',
|
txid: 'abc123',
|
||||||
signerAddr: 'bitcoincash:qptest',
|
signerAddr: 'bitcoincash:qptest',
|
||||||
seen: 1000,
|
seen: 1000,
|
||||||
|
blockHeight: 600100,
|
||||||
decoded: {
|
decoded: {
|
||||||
action: 'post',
|
action: 'post',
|
||||||
prefix: PREFIX_POST,
|
prefix: PREFIX_POST,
|
||||||
@@ -29,5 +30,6 @@ describe('#handlePost', () => {
|
|||||||
assert.equal(create.callCount, 1)
|
assert.equal(create.callCount, 1)
|
||||||
assert.equal(create.firstCall.args[0], 'abc123')
|
assert.equal(create.firstCall.args[0], 'abc123')
|
||||||
assert.equal(create.firstCall.args[1].text, 'hello memo')
|
assert.equal(create.firstCall.args[1].text, 'hello memo')
|
||||||
|
assert.equal(create.firstCall.args[1].blockHeight, 600100)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ describe('#handleSetProfilePic', () => {
|
|||||||
txid: 'abc123',
|
txid: 'abc123',
|
||||||
signerAddr: 'bitcoincash:qptest',
|
signerAddr: 'bitcoincash:qptest',
|
||||||
seen: 12345,
|
seen: 12345,
|
||||||
|
blockHeight: 600200,
|
||||||
decoded: { pushDatas: [combined] }
|
decoded: { pushDatas: [combined] }
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -30,5 +31,6 @@ describe('#handleSetProfilePic', () => {
|
|||||||
const [addr, data] = adapters.profilePicDb.create.firstCall.args
|
const [addr, data] = adapters.profilePicDb.create.firstCall.args
|
||||||
assert.equal(addr, 'bitcoincash:qptest')
|
assert.equal(addr, 'bitcoincash:qptest')
|
||||||
assert.equal(data.url, 'https://memo.cash/img/abc')
|
assert.equal(data.url, 'https://memo.cash/img/abc')
|
||||||
|
assert.equal(data.blockHeight, 600200)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user