diff --git a/.env.example b/.env.example index 4a71683..54a597e 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,4 @@ TON_BAG_ADDRESS=EQBOOMNqG0rvNm6vFGfR4qZl48BTDw_gYefVI4DQ70t9GoPC TASK_PROVIDER_MNEMONIC=xxx ... +TON_FILE_DOWNLOAD_PATH=downloads +TON_FILE_MOUNT_PATH=/root diff --git a/package.json b/package.json index cfddaf0..11a02a0 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@ton/crypto": "^3.2.0", "@ton/ton": "^13.11.2", "axios": "^1.7.2", + "bignumber.js": "^9.1.2", "dotenv": "^16.4.5", "js-sha256": "^0.11.0", "sequelize": "^6.35.2", diff --git a/src/config/index.ts b/src/config/index.ts index 4e81c64..2e3eff7 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -17,7 +17,8 @@ export const configs = { }, task: { minReward: BigInt(getEnvOrExit("TASK_MIN_REWARD", "0", false)), - maxFileSize: BigInt(getEnvOrExit("TASK_MAX_FILE_SIZE", "10485760", false)), + maxFileSize: BigInt(getEnvOrExit("TASK_MAX_FILE_SIZE", "1073741824", false)), + orderMinPrice: BigInt(getEnvOrExit("TASK_MIN_PRICE_G_D", "0", false)), providerMnemonic: getEnvOrExit("TASK_PROVIDER_MNEMONIC", ""), providerMinBalance: getEnvOrExit("TASK_PROVIDER_MIN_BALANCE", "1000000000"), submitStorageProofBefore: getEnvOrExit("TASK_SUBMIT_STORAGE_PROOF_BEFORE", "1800"), diff --git a/src/dao/common.ts b/src/dao/common.ts new file mode 100644 index 0000000..758b9de --- /dev/null +++ b/src/dao/common.ts @@ -0,0 +1,18 @@ +import {sequelize} from "../db"; +import {Order} from "./order"; +import {Config} from "./config"; +import {Task} from "./task"; +import {Transaction} from "./transaction"; + +const models: any[] = [Order, Config, Task, Transaction] + +export async function initDb() { + await sequelize.sync(); + for (const model of models) { + await model.model.sync({alter: true}); + } +} + +export async function disconnect() { + await sequelize.close(); +} diff --git a/src/dao/order.ts b/src/dao/order.ts index 6a6d2f0..90e6462 100644 --- a/src/dao/order.ts +++ b/src/dao/order.ts @@ -67,6 +67,11 @@ export class Order { allowNull: false, defaultValue: "{}" }, + order_price: { + type: DataTypes.DECIMAL(20, 6), + allowNull: false, + defaultValue: 0 + }, order_state: { type: DataTypes.INTEGER, allowNull: false, @@ -91,7 +96,7 @@ export class Order { }, { fields: ["order_state"] - } + }, ] } ) diff --git a/src/db/index.ts b/src/db/index.ts index a44dc0b..b3ebad3 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -8,10 +8,4 @@ export const sequelize = new Sequelize({ }); -export async function initDb() { - await sequelize.sync(); -} -export async function disconnect() { - await sequelize.close(); -} diff --git a/src/index.ts b/src/index.ts index ab5392c..dc7510f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -import {initDb} from "./db"; import {logger} from "./util/logger"; +import {initDb} from "./dao/common"; import {job} from "./service/job"; async function main() { diff --git a/src/service/task.ts b/src/service/task.ts index 1aaf9d0..bfc5c0c 100644 --- a/src/service/task.ts +++ b/src/service/task.ts @@ -8,6 +8,7 @@ import {sleep} from "../util/common"; import {sequelize} from "../db"; import {Task} from "../dao/task"; import {LAST_TASK_GENERATE_ORDER_ID} from "./constants"; +import {configs} from "../config"; export async function generateTasks() { while(true) { @@ -20,6 +21,15 @@ export async function generateTasks() { }, order_state: { [Op.gte]: OrderState.not_started + }, + file_size_in_bytes: { + [Op.lte]: configs.task.maxFileSize.toString() + }, + total_rewards: { + [Op.gte]: configs.task.minReward.toString() + }, + order_price: { + [Op.gte]: configs.task.orderMinPrice.toString() } }, limit: 10, diff --git a/src/wrapper/StorageContract.ts b/src/wrapper/StorageContract.ts index 1aa2283..80838f0 100644 --- a/src/wrapper/StorageContract.ts +++ b/src/wrapper/StorageContract.ts @@ -12,13 +12,13 @@ import { import {Address} from "@ton/ton"; import { op_recycle_undistributed_storage_fees, op_unregister_as_storage_provider, op_submit_storage_proof, - op_register_as_storage_provider, op_claim_storage_rewards + op_register_as_storage_provider, op_claim_storage_rewards, ONE_TON, ONE_DAY, ONE_GIGA } from './constants'; import {proofsIntoBody} from "./proofsutils"; -import {TonProvider} from "../util/ton"; import {logger} from "../util/logger"; import {OrderState} from "../type/common"; import {now} from "../util/common"; +import BigNumber from "bignumber.js"; export type StorageContractConfig = {}; @@ -287,6 +287,7 @@ export class StorageContract implements Contract { const cell = cells[0]; const orderInfo = this.loadOrderInfo(cell); const rewardsParams = this.loadRewardsParams(cell); + const orderPrice = this.loadOrderPrice(orderInfo.file_size_in_bytes, orderInfo.storage_period_in_sec, rewardsParams.total_rewards); return { address: this.address.toString(), ...orderInfo, @@ -294,6 +295,7 @@ export class StorageContract implements Contract { total_rewards: rewardsParams.total_rewards, period_finish: rewardsParams.period_finish, order_detail: JSON.stringify(rewardsParams), + order_price: orderPrice, order_state: this.parseOrderState(rewardsParams.started, rewardsParams.period_finish) }; } @@ -350,6 +352,13 @@ export class StorageContract implements Contract { } } + loadOrderPrice(file_size_in_bytes: number, storage_period_in_sec: number, total_rewards: number): string { + const tonReward = new BigNumber(total_rewards).multipliedBy(ONE_TON); + const periodInDay = new BigNumber(storage_period_in_sec).multipliedBy(ONE_DAY); + const fileSizeInGb = new BigNumber(file_size_in_bytes).multipliedBy(ONE_GIGA); + return tonReward.dividedBy(periodInDay).dividedBy(fileSizeInGb).toFixed(5, 1) + } + loadRewardsParams(cell: Cell): { started: number; total_storage_providers: number; diff --git a/src/wrapper/constants.ts b/src/wrapper/constants.ts index 0c2cef5..37fbf88 100644 --- a/src/wrapper/constants.ts +++ b/src/wrapper/constants.ts @@ -1,3 +1,6 @@ +export const ONE_DAY = 24 * 60 * 60; +export const ONE_TON = 1000000000; //10^9 +export const ONE_GIGA = 1024 * 1024 * 1024; export const default_storage_period = 60n * 60n * 24n * 180n; export const default_max_storage_proof_span = 60n * 60n * 24n; export const default_max_storage_providers_per_order = 30n; diff --git a/yarn.lock b/yarn.lock index 7ee0567..c09b71f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -515,6 +515,11 @@ base64-js@^1.3.1: resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bignumber.js@^9.1.2: + version "9.1.2" + resolved "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"