Skip to content

Commit

Permalink
Support ESM targets, add BCH support
Browse files Browse the repository at this point in the history
  • Loading branch information
mainnet-pat committed Dec 29, 2024
1 parent 8b367b3 commit fb74c25
Show file tree
Hide file tree
Showing 39 changed files with 3,052 additions and 45 deletions.
3 changes: 3 additions & 0 deletions bch/bch-processor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @subsquid/bch-processor

Data fetcher and mappings executor for BitcoinCash chain.
41 changes: 41 additions & 0 deletions bch/bch-processor/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@subsquid/bch-processor",
"type": "module",
"version": "1.0.0",
"description": "Data fetcher and mappings executor for BitcoinCash chain",
"license": "GPL-3.0-or-later",
"repository": "[email protected]:subsquid/squid.git",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"files": [
"lib",
"src"
],
"main": "lib/index.js",
"dependencies": {
"@bitauth/libauth": "^3.0.0",
"@subsquid/http-client": "^1.6.0",
"@subsquid/logger": "^1.3.3",
"@subsquid/rpc-client": "^4.11.0",
"@subsquid/util-internal": "^3.2.0",
"@subsquid/util-internal-archive-client": "^0.1.2",
"@subsquid/util-internal-hex": "^1.2.2",
"@subsquid/util-internal-ingest-tools": "^1.1.4",
"@subsquid/util-internal-processor-tools": "^4.1.1",
"@subsquid/util-internal-range": "^0.3.0",
"@subsquid/util-internal-validation": "^0.7.0",
"@subsquid/util-timeout": "^2.3.2",
"bitcoin-minimal": "^1.1.7",
"lru-cache": "^11.0.2",
"p2p-cash": "^1.1.12"
},
"devDependencies": {
"@types/node": "^18.18.14",
"typescript": "~5.5.4"
},
"scripts": {
"build": "rm -rf lib && tsc"
}
}
90 changes: 90 additions & 0 deletions bch/bch-processor/src/ds-archive/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {addErrorContext} from '@subsquid/util-internal'
import {ArchiveClient} from '@subsquid/util-internal-archive-client'
import {archiveIngest} from '@subsquid/util-internal-ingest-tools'
import {Batch, DataSource} from '@subsquid/util-internal-processor-tools'
import {getRequestAt, RangeRequest} from '@subsquid/util-internal-range'
import {cast} from '@subsquid/util-internal-validation'
import assert from 'assert'
import {Bytes32} from '../interfaces/base.js'
import {FieldSelection} from '../interfaces/data.js'
import {DataRequest} from '../interfaces/data-request.js'
import {
Block,
BlockHeader,
Transaction
} from '../mapping/entities.js'
import {setUpRelations} from '../mapping/relations.js'
import {getBlockValidator} from './schema.js'


const NO_FIELDS = {}


export class BchArchive implements DataSource<Block, DataRequest> {
constructor(private client: ArchiveClient) {}

getFinalizedHeight(): Promise<number> {
return this.client.getHeight()
}

async getBlockHash(height: number): Promise<Bytes32> {
let blocks = await this.client.query({
fromBlock: height,
toBlock: height,
includeAllBlocks: true
})
assert(blocks.length == 1)
return blocks[0].header.hash
}

async *getFinalizedBlocks(requests: RangeRequest<DataRequest>[], stopOnHead?: boolean | undefined): AsyncIterable<Batch<Block>> {
for await (let batch of archiveIngest({
requests,
client: this.client,
stopOnHead
})) {
let fields = getRequestAt(requests, batch.blocks[0].header.number)?.fields || NO_FIELDS

let blocks = batch.blocks.map(b => {
try {
return this.mapBlock(b, fields)
} catch(err: any) {
throw addErrorContext(err, {
blockHeight: b.header.number,
blockHash: b.header.hash
})
}
})

yield {blocks, isHead: batch.isHead, mempoolTransactions: []}
}
}

private mapBlock(rawBlock: unknown, fields: FieldSelection): Block {
let validator = getBlockValidator(fields)

let src = cast(validator, rawBlock)

let {height, hash, parentHash, ...hdr} = src.header
if (hdr.timestamp) {
hdr.timestamp = hdr.timestamp * 1000 // convert to ms
}

let header = new BlockHeader(height, hash, parentHash)
Object.assign(header, hdr)

let block = new Block(header)

if (src.transactions) {
for (let {...props} of src.transactions) {
let tx = new Transaction(header, 0)
Object.assign(tx, props)
block.transactions.push(tx)
}
}

setUpRelations(block)

return block
}
}
22 changes: 22 additions & 0 deletions bch/bch-processor/src/ds-archive/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {weakMemo} from '@subsquid/util-internal'
import {array, BYTES, object, option} from '@subsquid/util-internal-validation'
import {FieldSelection} from '../interfaces/data.js'
import {
getBlockHeaderProps,
getTxProps,
} from '../mapping/schema.js'


export const getBlockValidator = weakMemo((fields: FieldSelection) => {
let BlockHeader = object(getBlockHeaderProps(fields.block, true))

let Transaction = object({
hash: fields.transaction?.hash ? BYTES : undefined,
...getTxProps(fields.transaction, true),
})

return object({
header: BlockHeader,
transactions: option(array(Transaction)),
})
})
Loading

0 comments on commit fb74c25

Please sign in to comment.