Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/helium-admin-cli/src/create-boost-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export async function run(args: any = process.argv) {
rentReclaimAuthority: new PublicKey(argv.rentReclaimAuthority),
authority: subDaoAuth,
subDao,
startAuthority: new PublicKey(argv.startAuthority)
startAuthority: new PublicKey(argv.startAuthority),
})
.instruction(),
];
Expand Down
4 changes: 2 additions & 2 deletions packages/helium-admin-cli/src/update-boost-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ export async function run(args: any = process.argv) {
},
minimumPeriods: {
type: "number",
describe: "The new minimum number of periods"
describe: "The new minimum number of periods",
},
boostPrice: {
type: "string",
describe: "The boost price in bones"
describe: "The boost price in bones",
},
dntMint: {
type: "string",
Expand Down
17 changes: 16 additions & 1 deletion packages/hexboosting-sdk/src/pdas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,30 @@ import { PublicKey } from "@solana/web3.js";
import { PROGRAM_ID } from "./constants";
import BN from "bn.js";

enum DeviceType {
cbrsIndoor,
cbrsOutdoor,
wifiIndoor,
wifiOutdoor,
}

export function boostedHexKey(
boostConfig: PublicKey,
deviceType: any,
location: BN,
programId: PublicKey = PROGRAM_ID
) {
const locBuffer = Buffer.alloc(8);
locBuffer.writeBigUint64LE(BigInt(location.toString()));
const deviceTypeName = Object.keys(deviceType)[0];
let deviceTypeValue = DeviceType[deviceTypeName];
return PublicKey.findProgramAddressSync(
[Buffer.from("boosted_hex", "utf-8"), boostConfig.toBuffer(), locBuffer],
[
Buffer.from("boosted_hex", "utf-8"),
boostConfig.toBuffer(),
Buffer.from([deviceTypeValue]),
locBuffer,
],
programId
);
}
Expand Down
10 changes: 9 additions & 1 deletion packages/hexboosting-sdk/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ import {
} from "@helium/anchor-resolvers";
import { subDaoKey } from "@helium/helium-sub-daos-sdk";
import { PublicKey } from "@solana/web3.js";
import { boostedHexKey } from "./pdas";

export const hexboostingResolvers = combineResolvers(
heliumCommonResolver,
resolveIndividual(async ({ path, accounts }) => {
resolveIndividual(async ({ path, accounts, args }) => {
if (path[path.length - 1] === "subDao" && accounts.dntMint) {
return subDaoKey(accounts.dntMint as PublicKey)[0];
}
if (path[path.length - 1] === "boostedHex" && accounts.boostConfig && args[0].deviceType && args[0].location) {
return boostedHexKey(
accounts.boostConfig as PublicKey,
args[0].deviceType,
args[0].location
)[0]
}
}),
ataResolver({
instruction: "boostV0",
Expand Down
2 changes: 1 addition & 1 deletion programs/hexboosting/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hexboosting"
version = "0.0.5"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"

Expand Down
17 changes: 10 additions & 7 deletions programs/hexboosting/src/instructions/boost_v0.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::error::ErrorCode;
use crate::{error::ErrorCode, DeviceTypeV0};
use anchor_lang::prelude::*;
use anchor_spl::{
associated_token::AssociatedToken,
Expand All @@ -8,7 +8,7 @@ use mobile_entity_manager::CarrierV0;
use pyth_sdk_solana::load_price_feed_from_account_info;
use shared_utils::resize_to_fit;

use crate::{BoostConfigV0, BoostedHexV0};
use crate::{BoostConfigV0, BoostedHexV1};

pub const TESTING: bool = std::option_env!("TESTING").is_some();

Expand All @@ -20,6 +20,7 @@ pub struct BoostArgsV0 {
// invalid
pub version: u32,
pub amounts: Vec<BoostAmountV0>,
pub device_type: DeviceTypeV0,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
Expand All @@ -30,7 +31,7 @@ pub struct BoostAmountV0 {

fn get_space(boosted_hex: &AccountInfo) -> usize {
if boosted_hex.data_len() == 0 {
8 + 60 + std::mem::size_of::<BoostedHexV0>()
8 + 60 + std::mem::size_of::<BoostedHexV1>()
} else {
boosted_hex.data_len()
}
Expand Down Expand Up @@ -69,11 +70,11 @@ pub struct BoostV0<'info> {
init_if_needed,
payer = payer,
space = get_space(boosted_hex),
seeds = [b"boosted_hex", boost_config.key().as_ref(), &args.location.to_le_bytes()],
seeds = [b"boosted_hex", boost_config.key().as_ref(), &[(args.device_type as u8)], &args.location.to_le_bytes()],
bump,
constraint = boosted_hex.version == args.version @ ErrorCode::InvalidVersion,
)]
pub boosted_hex: Box<Account<'info, BoostedHexV0>>,
pub boosted_hex: Box<Account<'info, BoostedHexV1>>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, Token>,
pub associated_token_program: Program<'info, AssociatedToken>,
Expand All @@ -87,6 +88,7 @@ pub fn handler(ctx: Context<BoostV0>, args: BoostArgsV0) -> Result<()> {
ctx.accounts.boosted_hex.location = args.location;
ctx.accounts.boosted_hex.bump_seed = ctx.bumps["boosted_hex"];
ctx.accounts.boosted_hex.version += 1;
ctx.accounts.boosted_hex.device_type = args.device_type;

// Insert the new periods
let max_period = args
Expand All @@ -102,6 +104,7 @@ pub fn handler(ctx: Context<BoostV0>, args: BoostArgsV0) -> Result<()> {
.boosts_by_period
.resize(max_period + 1, 0);
}

let now = Clock::get()?.unix_timestamp;

for amount in args.amounts.clone() {
Expand Down Expand Up @@ -163,8 +166,8 @@ pub fn handler(ctx: Context<BoostV0>, args: BoostArgsV0) -> Result<()> {
let total_fee: u64 = args
.amounts
.iter()
.map(|amount| amount.amount as u64 * ctx.accounts.boost_config.boost_price)
.sum();
.map(|amount| (amount.amount as u64 * ctx.accounts.boost_config.boost_price))
.sum::<u64>();
let mobile_price_oracle =
load_price_feed_from_account_info(&ctx.accounts.price_oracle).map_err(|e| {
msg!("Pyth error {}", e);
Expand Down
4 changes: 2 additions & 2 deletions programs/hexboosting/src/instructions/close_boost_v0.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anchor_lang::prelude::*;

use crate::{BoostConfigV0, BoostedHexV0};
use crate::{BoostConfigV0, BoostedHexV1};

#[derive(Accounts)]
pub struct CloseBoostV0<'info> {
Expand All @@ -15,7 +15,7 @@ pub struct CloseBoostV0<'info> {
constraint = boosted_hex.is_expired(&boost_config),
has_one = boost_config
)]
pub boosted_hex: Box<Account<'info, BoostedHexV0>>,
pub boosted_hex: Box<Account<'info, BoostedHexV1>>,
}

pub fn handler(_ctx: Context<CloseBoostV0>) -> Result<()> {
Expand Down
4 changes: 2 additions & 2 deletions programs/hexboosting/src/instructions/start_boost_v0.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anchor_lang::prelude::*;

use crate::{BoostConfigV0, BoostedHexV0};
use crate::{BoostConfigV0, BoostedHexV1};

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
pub struct StartBoostArgsV0 {
Expand All @@ -18,7 +18,7 @@ pub struct StartBoostV0<'info> {
mut,
has_one = boost_config,
)]
pub boosted_hex: Box<Account<'info, BoostedHexV0>>,
pub boosted_hex: Box<Account<'info, BoostedHexV1>>,
}

pub fn handler(ctx: Context<StartBoostV0>, args: StartBoostArgsV0) -> Result<()> {
Expand Down
26 changes: 25 additions & 1 deletion programs/hexboosting/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ pub struct BoostConfigV0 {
pub start_authority: Pubkey,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Default, PartialEq)]
pub enum DeviceTypeV0 {
#[default]
CbrsIndoor = 0,
CbrsOutdoor = 1,
WifiIndoor = 2,
WifiOutdoor = 3,
}

#[account]
pub struct BoostedHexV0 {
pub boost_config: Pubkey,
Expand All @@ -36,7 +45,22 @@ pub struct BoostedHexV0 {
pub version: u32,
}

impl BoostedHexV0 {
#[account]
pub struct BoostedHexV1 {
pub device_type: DeviceTypeV0,
pub boost_config: Pubkey,
// Track changes to the boosted hex so client can pass what version it made a change to
pub version: u32,
pub location: u64,
// 0 if the boosting has not yet started. Avoding using an option here to keep serialization length
// consistent
pub start_ts: i64,
pub bump_seed: u8,
/// Each entry represents the boost multiplier for a given period
pub boosts_by_period: Vec<u8>,
}

impl BoostedHexV1 {
pub fn is_expired(&self, boost_config: &BoostConfigV0) -> bool {
if self.start_ts == 0 {
false
Expand Down
36 changes: 19 additions & 17 deletions tests/hexboosting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ import {
} from "@solana/web3.js";
import { BN } from "bn.js";
import { expect } from "chai";
import {
init as initHeliumEntityManager
} from "../packages/helium-entity-manager-sdk/src";
import { init as initHeliumEntityManager } from "../packages/helium-entity-manager-sdk/src";
import {
boostConfigKey,
boostedHexKey,
init
init,
} from "../packages/hexboosting-sdk";
import { init as initMobileEntityManager } from "../packages/mobile-entity-manager-sdk/src";
import { DataCredits } from "../target/types/data_credits";
Expand All @@ -39,10 +37,11 @@ import {
ensureHEMIdl,
ensureHSDIdl,
ensureMemIdl,
initTestDataCredits
initTestDataCredits,
} from "./utils/fixtures";
import { random } from "./utils/string";


describe("hexboosting", () => {
anchor.setProvider(anchor.AnchorProvider.local("http://127.0.0.1:8899"));

Expand Down Expand Up @@ -253,6 +252,7 @@ describe("hexboosting", () => {
.boostV0({
location: new BN(1),
version: 0,
deviceType: { wifiIndoor: {} },
amounts: [
{
period: 0,
Expand Down Expand Up @@ -293,7 +293,6 @@ describe("hexboosting", () => {
)
).amount;

console.log(pythPrice);
const expected = Number(
BigInt(toBN((6 * 0.005) / pythPrice, 6).toNumber())
);
Expand All @@ -302,8 +301,9 @@ describe("hexboosting", () => {
expected
);

const hex = await program.account.boostedHexV0.fetch(boostedHex!);
const hex = await program.account.boostedHexV1.fetch(boostedHex!);

expect(Object.keys(hex.deviceType)[0]).to.eq("wifiIndoor");
expect(hex.location.toNumber()).to.eq(1);
expect(hex.startTs.toNumber()).to.eq(0);
expect(hex.boostsByPeriod.toJSON().data).to.deep.eq([1, 1, 1, 1, 1, 1]);
Expand All @@ -315,6 +315,7 @@ describe("hexboosting", () => {
.boostV0({
location: new BN(1),
version: 0,
deviceType: { wifiIndoor: {} },
amounts: [
{
period: 0,
Expand Down Expand Up @@ -362,6 +363,7 @@ describe("hexboosting", () => {
.boostV0({
location: new BN(1),
version: 1,
deviceType: { wifiIndoor: {} },
amounts: [
{
period: 2,
Expand Down Expand Up @@ -393,21 +395,19 @@ describe("hexboosting", () => {
Number(expected)
);

const hex = await program.account.boostedHexV0.fetch(boostedHex!);
const hex = await program.account.boostedHexV1.fetch(boostedHex!);

expect(hex.boostsByPeriod.toJSON().data).to.deep.eq([
1,
1,
2,
1,
1,
1,
2,
1, 1, 2, 1, 1, 1, 2,
]);
});

it("allows starting a boost", async () => {
const boostedHex = boostedHexKey(boostConfigKey(mint)[0], new BN(1))[0];
const boostedHex = boostedHexKey(
boostConfigKey(mint)[0],
{ wifiIndoor: {} },
new BN(1)
)[0];
await program.methods
.startBoostV0({
startTs: new BN(1),
Expand All @@ -416,7 +416,7 @@ describe("hexboosting", () => {
boostedHex,
})
.rpc({ skipPreflight: true });
const acc = await program.account.boostedHexV0.fetch(boostedHex!);
const acc = await program.account.boostedHexV1.fetch(boostedHex!);
expect(acc.startTs.toNumber()).to.not.eq(0);
});

Expand All @@ -429,6 +429,7 @@ describe("hexboosting", () => {
beforeEach(async () => {
const boostedHex = boostedHexKey(
boostConfigKey(mint)[0],
{ wifiIndoor: {} },
new BN(1)
)[0];
await program.methods
Expand All @@ -444,6 +445,7 @@ describe("hexboosting", () => {
it("allows closing the boost when it's done", async () => {
const boostedHex = boostedHexKey(
boostConfigKey(mint)[0],
{ wifiIndoor: {} },
new BN(1)
)[0];
// Wait 7 seconds so it is fully expired
Expand Down
6 changes: 3 additions & 3 deletions tests/utils/compression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export async function createCompressionNft({
creators: [],
editionNonce: 0,
tokenProgramVersion: TokenProgramVersion.Original,
tokenStandard: TokenStandard.Fungible,
tokenStandard: TokenStandard.NonFungible,
uses: null,
collection: null,
primarySaleHappened: false,
Expand Down Expand Up @@ -126,7 +126,7 @@ export async function createCompressionNft({
await bubblegum.methods
.mintToCollectionV1({
...metadata,
tokenStandard: { fungible: {} },
tokenStandard: { nonFungible: {} },
tokenProgramVersion: { original: {} },
})
.accounts({
Expand All @@ -144,7 +144,7 @@ export async function createCompressionNft({
await bubblegum.methods
.mintV1({
...metadata,
tokenStandard: { fungible: {} },
tokenStandard: { nonFungible: {} },
tokenProgramVersion: { original: {} },
})
.accounts({
Expand Down
Loading