From: Chris Duncan Date: Sat, 8 Aug 2026 08:35:57 +0000 (-0700) Subject: Miscellaneous fixes. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=ae8fb70aa0bb11e717aa2ee65e58503f340851a9;p=libnemo.git Miscellaneous fixes. --- diff --git a/src/index.ts b/src/index.ts index 65b53e9..933036f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ declare global { export { Account } from './lib/account' export { Block } from './lib/block' export { Blake2b } from './lib/crypto' -export { VaultError } from './lib/errors' +export * from './lib/errors' export { Ledger } from './lib/ledger' export { Rolodex } from './lib/rolodex' export { Rpc } from './lib/rpc' diff --git a/src/lib/block/index.ts b/src/lib/block/index.ts index 9fa4114..afa614c 100644 --- a/src/lib/block/index.ts +++ b/src/lib/block/index.ts @@ -3,8 +3,8 @@ import { NanoPow } from 'nano-pow' import { Account } from '../account' -import { DIFFICULTY_RECEIVE, DIFFICULTY_SEND, PREAMBLE } from '../constants' -import { bytes, dec, hex } from '../convert' +import { BURN_PUBLIC_KEY, DIFFICULTY_RECEIVE, DIFFICULTY_SEND, PREAMBLE } from '../constants' +import { bytes, dec, hex, utf8 } from '../convert' import { Blake2b } from '../crypto' import { Rpc } from '../rpc' import { ProcessRequest } from '../rpc/process' @@ -32,7 +32,7 @@ export class Block { _validate(block) } - subtype?: 'send' | 'receive' | 'change' + subtype?: 'change' | 'epoch' | 'receive' | 'send' account: Account balance: bigint previous: Bytes @@ -72,7 +72,7 @@ export class Block { throw new TypeError('Invalid account') } balance ??= account.balance - previous ??= account.frontier ?? '00' + previous ??= account.frontier ?? BURN_PUBLIC_KEY representative ??= account.representative if (typeof balance !== 'bigint' && typeof balance !== 'number' && typeof balance !== 'string') { throw new TypeError('Account balance is unknown') @@ -80,6 +80,9 @@ export class Block { if (typeof previous !== 'string') { throw new TypeError('Account frontier is unknown') } + if (!(/^[0-9A-F]{64}$/i.test(previous))) { + throw new RangeError('Invalid frontier hash') + } this.account = account this.balance = convert(balance, 'raw', 'raw', 'bigint') this.previous = hex.toBytes(previous, 32) @@ -169,6 +172,9 @@ export class Block { * @returns {Block} This block unchanged */ epoch (): Block { + const special = utf8.toHex('epoch v2 block') + this.link = hex.toBytes(`${special}000000000000000000000000000000000000`) + this.subtype = 'epoch' return this } @@ -182,8 +188,9 @@ export class Block { * @returns {Block} This block with balance, link, and subtype configured */ open (sendBlock: string | Block, amount: bigint | number | string, unit?: string): Block { - this.previous.fill(0) - return _receive(this, sendBlock, amount, unit) + const openBlock = _receive(this, sendBlock, amount, unit) + openBlock.previous.fill(0) + return openBlock } /** @@ -237,6 +244,9 @@ export class Block { if (this.subtype == null) { throw new Error('Block is missing subtype. Call respective method and try again.') } + if (this.subtype === 'epoch') { + throw new Error('Only change, receive, and send blocks can be processed.') + } if (this.work == null) await this.pow() const data: ProcessRequest = { async: false, diff --git a/src/lib/rolodex.ts b/src/lib/rolodex.ts index 9791ff5..a849986 100644 --- a/src/lib/rolodex.ts +++ b/src/lib/rolodex.ts @@ -53,7 +53,7 @@ export class Rolodex { if (existingName === name) { return true } - const data: { [address: string]: { id: string, name: string } } | { [name: string]: { id: string, addresses: string[] } } = {} + const data: { [address: string]: { id: string, name: string } } | { [name: string]: { id: string, addresses: string[] } } = Object.create(null) data[address] = { id: address, name diff --git a/src/lib/rpc/block_info.ts b/src/lib/rpc/block_info.ts index 19320ba..5344c7f 100644 --- a/src/lib/rpc/block_info.ts +++ b/src/lib/rpc/block_info.ts @@ -48,11 +48,11 @@ export function block_info (body: unknown): BlockInfoResponse { && 'contents' in body && body.contents != null && typeof body.contents === 'object' && 'account' in body.contents && typeof body.contents.account === 'string' && 'balance' in body.contents && typeof body.contents.balance === 'string' - && 'link' in body.contents && typeof body.contents.link === 'string' + && 'link' in body.contents && typeof body.contents.link === 'string' && /^[0-9A-F]{64}$/i.test(body.contents.link) && 'link_as_account' in body.contents && typeof body.contents.link_as_account === 'string' - && 'previous' in body.contents && typeof body.contents.previous === 'string' + && 'previous' in body.contents && typeof body.contents.previous === 'string' && /^[0-9A-F]{64}$/i.test(body.contents.previous) && 'representative' in body.contents && typeof body.contents.representative === 'string' - && 'signature' in body.contents && typeof body.contents.signature === 'string' + && 'signature' in body.contents && typeof body.contents.signature === 'string' && /^[0-9A-F]{128}$/i.test(body.contents.signature) && 'type' in body.contents && body.contents.type === 'state' && 'work' in body.contents && typeof body.contents.work === 'string' ) { diff --git a/src/lib/vault/index.ts b/src/lib/vault/index.ts index a021204..52811d6 100644 --- a/src/lib/vault/index.ts +++ b/src/lib/vault/index.ts @@ -128,7 +128,7 @@ export class Vault { #report (message: unknown): void { if (message == null || typeof message !== 'object') return - if (!('data' in message) || message.data == null || typeof message !== 'object') return + if (!('data' in message) || message.data == null || typeof message.data !== 'object') return const results = message.data as Record const { taskUrl, taskId, error, isLocked } = results if (taskUrl === this.#url) { diff --git a/src/lib/wallet/unopened.ts b/src/lib/wallet/unopened.ts index ab8fb8b..49beff1 100644 --- a/src/lib/wallet/unopened.ts +++ b/src/lib/wallet/unopened.ts @@ -42,5 +42,5 @@ export async function _unopened (wallet: Wallet, rpc: unknown, batchSize: unknow if (to >= 0xffffffff) { throw new RangeError('Max index reached') } - return await _unopened(wallet, rpc, batchSize, to) + return await _unopened(wallet, rpc, batchSize, to + 1) }