Skip to content

Commit

Permalink
feat(#373): replace clockwork (#388)
Browse files Browse the repository at this point in the history
* wip

* end epoch logic added

* combined script

* remove unused conditional

* Revert prittier changes for better diff
  • Loading branch information
bryzettler authored Aug 31, 2023
1 parent a4a3780 commit 55033c7
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 0 deletions.
60 changes: 60 additions & 0 deletions packages/crons/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "@helium/crons",
"version": "1.0.0",
"description": "scripts to run on a schedule",
"private": true,
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/helium/helium-program-library"
},
"main": "./lib/cjs/index.js",
"module": "./lib/esm/src/index.js",
"types": "./lib/types/src/index.d.ts",
"sideEffects": false,
"files": [
"lib"
],
"exports": {
"import": "./lib/esm/src/index.js",
"require": "./lib/cjs/index.js",
"types": "./lib/types/src/index.d.ts"
},
"scripts": {
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"precommit": "npx git-format-staged -f 'prettier --ignore-unknown --stdin --stdin-filepath \"{}\"' .",
"clean": "npx shx mkdir -p lib && npx shx rm -rf lib",
"package": "npx shx mkdir -p lib/cjs lib/esm",
"prebuild": "npm run clean && npm run package"
},
"dependencies": {
"@coral-xyz/anchor": "^0.26.0",
"@helium/fanout-sdk": "^0.2.21",
"@helium/helium-sub-daos-sdk": "^0.2.21",
"@helium/lazy-distributor-sdk": "^0.2.21",
"@helium/mobile-entity-manager-sdk": "^0.2.21",
"@helium/price-oracle-sdk": "^0.2.21",
"@helium/spl-utils": "^0.2.21",
"@helium/treasury-management-sdk": "^0.2.21",
"@solana/spl-token": "^0.3.8",
"@solana/web3.js": "^1.78.4",
"axios": "^1.3.6",
"bn.js": "^5.2.0",
"bs58": "^4.0.1",
"yargs": "^17.7.1"
},
"devDependencies": {
"@types/bs58": "^4.0.1",
"@types/bn.js": "^5.1.0",
"@types/yargs": "^17.0.24",
"git-format-staged": "^2.1.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.9.1",
"typescript": "^4.8.4",
"yarn": "^1.22.18"
}
}
163 changes: 163 additions & 0 deletions packages/crons/src/end-epoch-and-distribute-hst.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import * as anchor from '@coral-xyz/anchor';
import { fanoutKey, init as initHydra } from '@helium/fanout-sdk';
import {
EPOCH_LENGTH,
currentEpoch,
daoEpochInfoKey,
daoKey,
init as initDao,
subDaoEpochInfoKey,
} from '@helium/helium-sub-daos-sdk';
import { HNT_MINT, chunks } from '@helium/spl-utils';
import { getAccount } from '@solana/spl-token';
import { ComputeBudgetProgram as CBP, PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
import bs58 from 'bs58';
import os from 'os';
import yargs from 'yargs/yargs';

const FANOUT_NAME = 'HST';
(async (args: any = process.argv) => {
const yarg = yargs(args).options({
wallet: {
alias: 'k',
describe: 'Anchor wallet keypair',
default: `${os.homedir()}/.config/solana/id.json`,
},
url: {
alias: 'u',
default: 'http://127.0.0.1:8899',
describe: 'The solana url',
},
});

const argv = await yarg.argv;
process.env.ANCHOR_WALLET = argv.wallet;
process.env.ANCHOR_PROVIDER_URL = argv.url;
anchor.setProvider(anchor.AnchorProvider.local(argv.url));

const provider = anchor.getProvider() as anchor.AnchorProvider;
const heliumSubDaosProgram = await initDao(provider);
const hntMint = HNT_MINT;
const unixNow = new Date().valueOf() / 1000;
const [dao] = daoKey(hntMint);
const subDaos = await heliumSubDaosProgram.account.subDaoV0.all([
{
memcmp: {
offset: 8,
bytes: bs58.encode(dao.toBuffer()),
},
},
]);

let targetTs = subDaos.reduce(
(acc, subDao) => BN.min(acc, subDao.account.vehntLastCalculatedTs),
new BN(unixNow)
);

while (targetTs.toNumber() < unixNow) {
const epoch = currentEpoch(targetTs);
console.log(epoch.toNumber(), targetTs.toNumber());
const [daoEpoch] = daoEpochInfoKey(dao, targetTs);
const daoEpochInfo =
await heliumSubDaosProgram.account.daoEpochInfoV0.fetchNullable(daoEpoch);

if (!daoEpochInfo?.doneCalculatingScores) {
for (const subDao of subDaos) {
const [subDaoEpoch] = subDaoEpochInfoKey(subDao.publicKey, targetTs);
const subDaoEpochInfo =
await heliumSubDaosProgram.account.subDaoEpochInfoV0.fetchNullable(
subDaoEpoch
);

if (!subDaoEpochInfo?.doneCalculatingScores) {
try {
await heliumSubDaosProgram.methods
.calculateUtilityScoreV0({ epoch })
.accounts({ subDao: subDao.publicKey })
.preInstructions([CBP.setComputeUnitLimit({ units: 350000 })])
.rpc({ skipPreflight: true });
} catch (err: any) {
console.log(
`Failed to calculate utility score for ${subDao.account.dntMint.toBase58()}: ${
err.message
}`
);
}
}
}
}

if (!daoEpochInfo?.doneIssuingRewards) {
for (const subDao of subDaos) {
const [subDaoEpoch] = subDaoEpochInfoKey(subDao.publicKey, targetTs);
const subDaoEpochInfo =
await heliumSubDaosProgram.account.subDaoEpochInfoV0.fetchNullable(
subDaoEpoch
);

if (!subDaoEpochInfo?.doneIssuingRewards) {
try {
await heliumSubDaosProgram.methods
.issueRewardsV0({ epoch })
.accounts({ subDao: subDao.publicKey })
.rpc({ skipPreflight: true });
} catch (err: any) {
console.log(
`Failed to issue rewards for ${subDao.account.dntMint.toBase58()}: ${
err.message
}`
);
}
}
}
}

if (!daoEpochInfo?.doneIssuingHstPool) {
try {
await heliumSubDaosProgram.methods
.issueHstPoolV0({ epoch })
.accounts({ dao })
.rpc({ skipPreflight: true });
} catch (err: any) {
console.log(`Failed to issue hst pool: ${err.message}`);
}
}

targetTs = targetTs.add(new BN(EPOCH_LENGTH));
}

const hydraProgram = await initHydra(provider);
const [fanoutK] = fanoutKey(FANOUT_NAME);
const members = (await hydraProgram.account.fanoutVoucherV0.all()).filter(
(m) => m.account.fanout.equals(fanoutK)
);

await Promise.all(
chunks(members, 100).map(async (chunk) => {
await Promise.all(
chunk.map(async (member) => {
const mint = member.account.mint;
const owners = await provider.connection.getTokenLargestAccounts(
mint
);
const owner = (
await getAccount(provider.connection, owners.value[0].address)
).owner;

console.log('Distributing for mint', mint.toBase58());

await hydraProgram.methods
.distributeV0()
.accounts({
payer: provider.wallet.publicKey,
fanout: fanoutK,
owner,
mint,
})
.rpc({ skipPreflight: true });
})
);
})
);
})();
7 changes: 7 additions & 0 deletions packages/crons/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.cjs.json",
"include": ["src"],
"compilerOptions": {
"outDir": "lib/cjs"
}
}
8 changes: 8 additions & 0 deletions packages/crons/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.esm.json",
"include": ["src"],
"compilerOptions": {
"outDir": "lib/esm",
"declarationDir": "lib/types"
}
}
50 changes: 50 additions & 0 deletions packages/crons/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"extends": "../../tsconfig.root.json",
"references": [
{
"path": "../spl-utils"
},
{
"path": "../idls"
},
{
"path": "../fanout-sdk"
},
{
"path": "../distributor-oracle"
},
{
"path": "../data-credits-sdk"
},
{
"path": "../circuit-breaker-sdk"
},
{
"path": "../helium-sub-daos-sdk"
},
{
"path": "../lazy-distributor-sdk"
},
{
"path": "../helium-entity-manager-sdk"
},
{
"path": "../mobile-entity-manager-sdk"
},
{
"path": "../treasury-management-sdk"
},
{
"path": "../price-oracle-sdk"
},
{
"path": "../rewards-oracle-sdk"
},
{
"path": "./tsconfig.cjs.json"
},
{
"path": "./tsconfig.esm.json"
}
]
}

0 comments on commit 55033c7

Please sign in to comment.