Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 Add matching related operations command #30

Merged
merged 2 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,21 @@ function matchingCommand(yargs: yargs.Argv<{}>): {
type: "string",
},
})
.command("getCarsIdsWithState", "Get cars Ids and matching state", {
replicaIndex: {
description: "Replica index",
alias: "r",
demandOption: true,
type: "number",
},

path: {
description: "cars Ids file path",
alias: "p",
demandOption: true,
type: "string",
},
})
.command("bidding", "Bidding matching", {
matchingId: {
description: "Matching Id",
Expand All @@ -299,6 +314,38 @@ function matchingCommand(yargs: yargs.Argv<{}>): {
type: "string",
},
})
.command("closeMatching", "Close matching", {
matchingId: {
description: "Matching Id",
alias: "m",
demandOption: true,
type: "number",
},
})
.command("cancelMatching", "Cancel matching", {
matchingId: {
description: "Matching Id",
alias: "m",
demandOption: true,
type: "number",
},
})
.command("pauseMatching", "Pause matching", {
matchingId: {
description: "Matching Id",
alias: "m",
demandOption: true,
type: "number",
},
})
.command("resumeMatching", "Resume matching", {
matchingId: {
description: "Matching Id",
alias: "m",
demandOption: true,
type: "number",
},
})
.command("getMatchingState", "Get matching state", {
matchingId: {
description:
Expand Down Expand Up @@ -552,6 +599,8 @@ async function dataset(
datasetId: Number(argv.datasetId),
})
break
default:
console.log("Unknown command.")
}
}

Expand Down Expand Up @@ -593,19 +642,52 @@ async function matching(
path: String(argv.path),
})
break
case "getCarsIdsWithState":
await new Matching().getCarsIdsWithState({
context,
replicaIndex: Number(argv.replicaIndex),
path: String(argv.path),
})
break
case "bidding":
await new Matching().bidding({
context,
matchingId: Number(argv.matchingId),
amount: BigInt(String(argv.amount)),
})
break
case "closeMatching":
await new Matching().closeMatching({
context,
matchingId: Number(argv.matchingId),
})
break
case "cancelMatching":
await new Matching().cancelMatching({
context,
matchingId: Number(argv.matchingId),
})
break
case "pauseMatching":
await new Matching().pauseMatching({
context,
matchingId: Number(argv.matchingId),
})
break
case "resumeMatching":
await new Matching().resumeMatching({
context,
matchingId: Number(argv.matchingId),
})
break
case "getMatchingState":
await new Matching().getMatchingState({
context,
matchingId: Number(argv.matchingId),
})
break
default:
console.log("Unknown command.")
}
}

Expand Down Expand Up @@ -665,6 +747,8 @@ async function storage(
matchingId: Number(argv.matchingId),
})
break
default:
console.log("Unknown command.")
}
}

Expand Down Expand Up @@ -704,5 +788,7 @@ async function finance(
})
)
break
default:
console.log("Unknown command.")
}
}
165 changes: 162 additions & 3 deletions src/matching/repo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
********************************************************************************/

import fs from "fs"
import { MatchingState } from "@dataswapjs/dataswapjs"
import { MatchingState, Car } from "@dataswapjs/dataswapjs"
import { handleEvmError, logMethodCall } from "../../shared/utils/utils"
import {
MatchingMetadataSubmitInfo,
Expand Down Expand Up @@ -132,6 +132,86 @@ export class Matching {
return true
}

/**
* Closes a matching with the specified matching ID.
* @param options - An object containing the context and matching ID.
* @returns A Promise that resolves to true if the matching is closed successfully.
*/
@logMethodCall(["context"])
async closeMatching(options: {
context: Context
matchingId: number
}): Promise<boolean> {
options.context.evm.matchingBids
.getWallet()
.add(process.env.privateKey!)
await handleEvmError(
options.context.evm.matchingBids.closeMatching(options.matchingId)
)
return true
}

/**
* Cancels a matching with the specified matching ID.
* @param options - An object containing the context and matching ID.
* @returns A Promise that resolves to true if the matching is canceled successfully.
*/
@logMethodCall(["context"])
async cancelMatching(options: {
context: Context
matchingId: number
}): Promise<boolean> {
options.context.evm.matchingBids
.getWallet()
.add(process.env.datasetPreparerPrivateKey!)
await handleEvmError(
options.context.evm.matchingBids.cancelMatching(options.matchingId)
)
return true
}

/**
* Pauses a matching with the specified matching ID.
* @param options - An object containing the context and matching ID.
* @returns A Promise that resolves to true if the matching is paused successfully.
*/
@logMethodCall(["context"])
async pauseMatching(options: {
context: Context
matchingId: number
}): Promise<boolean> {
options.context.evm.matchingMetadata
.getWallet()
.add(process.env.datasetPreparerPrivateKey!)
await handleEvmError(
options.context.evm.matchingMetadata.pauseMatching(
options.matchingId
)
)
return true
}

/**
* Resumes a matching with the specified matching ID.
* @param options - An object containing the context and matching ID.
* @returns A Promise that resolves to true if the matching is resumed successfully.
*/
@logMethodCall(["context"])
async resumeMatching(options: {
context: Context
matchingId: number
}): Promise<boolean> {
options.context.evm.matchingMetadata
.getWallet()
.add(process.env.datasetPreparerPrivateKey!)
await handleEvmError(
options.context.evm.matchingMetadata.resumeMatching(
options.matchingId
)
)
return true
}

/**
* Retrieves the IDs of cars based on the provided JSON file path.
*
Expand All @@ -143,13 +223,50 @@ export class Matching {
context: Context
path: string
}): Promise<bigint[]> {
const ids = JSON.parse(fs.readFileSync(options.path).toString())
const cars = JSON.parse(fs.readFileSync(options.path).toString())

return await handleEvmError(
options.context.evm.carstore.getCarsIds(ids.carsHash)
options.context.evm.carstore.getCarsIds(cars.carsHash)
)
}

/**
* Retrieves the IDs of cars based on the provided JSON file path.
*
* @param options An object containing the context and the path to the JSON file.
* @returns A Promise resolving to an array of BigInt values representing the car IDs.
*/
@logMethodCall(["context"])
async getCarsIdsWithState(options: {
context: Context
replicaIndex: number
path: string
}): Promise<{ matchinged: string[]; unmatching: string[] }> {
const cars = JSON.parse(fs.readFileSync(options.path).toString())

const ids: bigint[] = await handleEvmError(
options.context.evm.carstore.getCarsIds(cars.carsHash)
)
const unmatching: bigint[] = []
const matchinged: bigint[] = []

for (const id of ids) {
const car = (await handleEvmError(
options.context.evm.carstore.getCar(id)
)) as Car

if (
car.matchingIds &&
car.matchingIds[options.replicaIndex] != (undefined || 0)
) {
matchinged.push(id)
} else {
unmatching.push(id)
}
}
return await this.formatIdsWithState({ matchinged, unmatching })
}

/**
* Places a bid on a matching.
* @param options - The options object containing the context, matching ID, and bid amount.
Expand Down Expand Up @@ -189,4 +306,46 @@ export class Matching {
)
)
}

/**
* Formats the given IDs with their state (matchinged/unmatching).
* @param options The options object containing unmatching and matchinged IDs.
* @returns A Promise resolving to an object with formatted unmatching and matchinged IDs.
*/
private async formatIdsWithState(options: {
matchinged: bigint[]
unmatching: bigint[]
}): Promise<{ matchinged: string[]; unmatching: string[] }> {
const unmatchingIds: string[] = this.formatRange(options.unmatching)
const matchingedIds: string[] = this.formatRange(options.matchinged)

return { matchinged: matchingedIds, unmatching: unmatchingIds }
}

/**
* Formats the given array of IDs into ranges (e.g., [1, 2, 3, 5] => ["1-3", "5"]).
* @param ids The array of IDs to be formatted.
* @returns An array of strings representing formatted ranges of IDs.
*/
private formatRange(ids: bigint[]): string[] {
// Sort the IDs and remove duplicates
const sortedIds = Array.from(new Set(ids)).sort(
(a, b) => Number(a) - Number(b)
)
const ranges: string[] = []

let start = sortedIds[0]
let end = sortedIds[0]
for (let i = 1; i < sortedIds.length; i++) {
if (sortedIds[i] - end === BigInt(1)) {
end = sortedIds[i]
} else {
ranges.push(start === end ? `${start}` : `${start}-${end}`)
start = end = sortedIds[i]
}
}
ranges.push(start === end ? `${start}` : `${start}-${end}`)

return ranges
}
}
Loading