Skip to content

Commit

Permalink
feat: support partial search for rich indexer
Browse files Browse the repository at this point in the history
  • Loading branch information
homura committed Jun 19, 2024
1 parent f89a2ce commit dd042d7
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/base/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Hexadecimal, HexString } from "./primitive";
import { Logger } from "./logger";
import { isScriptWrapper } from "./helpers";

export type SearchMode = "exact" | "prefix";
export type SearchMode = "exact" | "prefix" | "partial";

export type DataWithSearchMode = {
searchMode: SearchMode;
Expand Down
54 changes: 47 additions & 7 deletions packages/ckb-indexer/src/ckbIndexerFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type LumosQueryOptions = Pick<
| "outputDataLenRange"
| "outputCapacityRange"
| "scriptLenRange"
| "scriptSearchMode"
>;

/**
Expand Down Expand Up @@ -71,7 +72,7 @@ function convertQueryOptionToLumosSearchKey(
scriptType: "lock",
scriptSearchMode: instanceOfScriptWrapper(queryLock)
? queryLock.searchMode || "prefix"
: "prefix",
: queryOptions.scriptSearchMode || "prefix",
filter: {},
};
searchKeyType && (searchKey.filter.script = searchKeyType);
Expand All @@ -81,7 +82,7 @@ function convertQueryOptionToLumosSearchKey(
scriptType: "type",
scriptSearchMode: instanceOfScriptWrapper(queryType)
? queryType.searchMode || "prefix"
: "prefix",
: queryOptions.scriptSearchMode || "prefix",
filter: {},
};
} else {
Expand Down Expand Up @@ -139,9 +140,21 @@ function filterByLumosQueryOptions(
.slice(0, expectPrefix.length);
return bytes.equal(expectPrefix, actualPrefix);
});
} else {
} else if (
instanceOfDataWithSearchMode(options.data) &&
options.data.searchMode === "partial"
) {
const search: DataWithSearchMode = options.data;
filteredCells = filteredCells.filter((cell) =>
bytes.indexOf(cell.data, search.data)
);
} else if (
typeof options.data === "string" &&
options.data.startsWith("0x")
) {
const searchBytes = options.data;
filteredCells = filteredCells.filter((cell) => {
const expectPrefix = bytes.bytify(options.data as string);
const expectPrefix = bytes.bytify(searchBytes);
const actualPrefix = bytes
.bytify(cell.data)
.slice(0, expectPrefix.length);
Expand All @@ -160,12 +173,11 @@ export function filterByLumosSearchKey(
cell: Cell,
searchKey: LumosSearchKey
): boolean {
const isExactMode = searchKey.scriptSearchMode === "exact";
const { cellOutput } = cell;
const { scriptType, script, filter } = searchKey;

// Search mode
if (isExactMode) {
if (searchKey.scriptSearchMode === "exact") {
if (scriptType === "lock") {
if (
!bytes.equal(
Expand All @@ -187,7 +199,7 @@ export function filterByLumosSearchKey(
}
}
// Prefix mode
} else {
} else if (searchKey.scriptSearchMode === "prefix") {
if (scriptType === "lock") {
if (!checkScriptWithPrefixMode(cellOutput.lock, script)) {
return false;
Expand All @@ -197,6 +209,16 @@ export function filterByLumosSearchKey(
return false;
}
}
} else if (searchKey.scriptSearchMode === "partial") {
if (scriptType === "lock") {
if (!checkScriptWithPartialMode(cellOutput.lock, script)) {
return false;
}
} else {
if (!checkScriptWithPartialMode(cellOutput.type, script)) {
return false;
}
}
}

// the "exact" mode works only on "SearchKey.script",
Expand Down Expand Up @@ -284,6 +306,24 @@ function checkScriptWithPrefixMode(
return true;
}

function checkScriptWithPartialMode(
script: Script | undefined,
filterScript: Script
): boolean {
if (!script) return false;

// codeHash should always be 32 bytes, so it only supports exact match mode
if (!bytes.equal(filterScript.codeHash, script.codeHash)) {
return false;
}

if (script.hashType !== filterScript.hashType) {
return false;
}

return bytes.indexOf(script.args, filterScript.args) > -1;
}

function checkScriptLenRange(
script: Script | undefined,
scriptLenRange: HexadecimalRange
Expand Down
7 changes: 6 additions & 1 deletion packages/ckb-indexer/src/collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export class CKBCellCollector implements BaseCellCollector {
if (queryLock) {
if (instanceOfScriptWrapper(queryLock)) {
validators.ValidateScript(queryLock.script);
query.scriptSearchMode = queryLock.searchMode;
query.lock = queryLock.script;
}
}
Expand All @@ -152,6 +153,7 @@ export class CKBCellCollector implements BaseCellCollector {
instanceOfScriptWrapper(query.type)
) {
validators.ValidateScript(query.type.script);
query.scriptSearchMode = query.type.searchMode;
query.type = query.type.script;
}
}
Expand Down Expand Up @@ -207,7 +209,10 @@ export class CKBCellCollector implements BaseCellCollector {
"Content-Type": "application/json",
},
});
if (res.status !== 200) {

const HTTP_SUCCESS_STATUS = 200;

if (res.status !== HTTP_SUCCESS_STATUS) {
throw new Error(`indexer request failed with HTTP code ${res.status}`);
}
const result = await res.json();
Expand Down
2 changes: 1 addition & 1 deletion packages/ckb-indexer/src/rpcType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type CellOutput = {

export type HexadecimalRange = [Hexadecimal, Hexadecimal];
export type ScriptType = "type" | "lock";
export type ScriptSearchMode = "prefix" | "exact";
export type ScriptSearchMode = "prefix" | "exact" | "partial";

export interface SearchFilter {
script?: Script;
Expand Down
2 changes: 1 addition & 1 deletion packages/ckb-indexer/src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { BIish } from "@ckb-lumos/bi";

export type ScriptType = "type" | "lock";
export type Order = "asc" | "desc";
export type ScriptSearchMode = "prefix" | "exact";
export type ScriptSearchMode = "prefix" | "exact" | "partial";

export interface CKBIndexerQueryOptions extends QueryOptions {
outputDataLenRange?: HexadecimalRange;
Expand Down
2 changes: 1 addition & 1 deletion packages/rpc/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export namespace CKBComponents {
export type ScriptType = "type" | "lock";
export type Order = "asc" | "desc";
export type IOType = "input" | "output" | "both";
export type ScriptSearchMode = "prefix" | "exact";
export type ScriptSearchMode = "prefix" | "exact" | "partial";

export interface IndexerCell {
blockNumber: BlockNumber;
Expand Down
2 changes: 1 addition & 1 deletion packages/rpc/src/types/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ export namespace RPC {

export type HexadecimalRange = [string, string];
export type ScriptType = "type" | "lock";
export type ScriptSearchMode = "prefix" | "exact";
export type ScriptSearchMode = "prefix" | "exact" | "partial";

export interface SearchFilter {
script?: Script;
Expand Down

0 comments on commit dd042d7

Please sign in to comment.