mc/feature gating (#129)

* feature gating

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* Fixes from review

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-08-01 12:56:29 +02:00 committed by GitHub
parent 16e1e83e26
commit e8e774a1a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 70 additions and 18 deletions

View File

@ -6,7 +6,7 @@ use anchor_spl::token::{self, CloseAccount, Token, TokenAccount};
pub struct GroupClose<'info> { pub struct GroupClose<'info> {
#[account( #[account(
mut, mut,
constraint = group.load()?.testing == 1, constraint = group.load()?.is_testing(),
has_one = admin, has_one = admin,
has_one = insurance_vault, has_one = insurance_vault,
close = sol_destination close = sol_destination

View File

@ -38,7 +38,12 @@ pub struct GroupCreate<'info> {
pub rent: Sysvar<'info, Rent>, pub rent: Sysvar<'info, Rent>,
} }
pub fn group_create(ctx: Context<GroupCreate>, group_num: u32, testing: u8) -> Result<()> { pub fn group_create(
ctx: Context<GroupCreate>,
group_num: u32,
testing: u8,
version: u8,
) -> Result<()> {
let mut group = ctx.accounts.group.load_init()?; let mut group = ctx.accounts.group.load_init()?;
group.creator = ctx.accounts.creator.key(); group.creator = ctx.accounts.creator.key();
group.admin = ctx.accounts.creator.key(); group.admin = ctx.accounts.creator.key();
@ -48,5 +53,6 @@ pub fn group_create(ctx: Context<GroupCreate>, group_num: u32, testing: u8) -> R
group.bump = *ctx.bumps.get("group").ok_or(MangoError::SomeError)?; group.bump = *ctx.bumps.get("group").ok_or(MangoError::SomeError)?;
group.group_num = group_num; group.group_num = group_num;
group.testing = testing; group.testing = testing;
group.version = version;
Ok(()) Ok(())
} }

View File

@ -6,7 +6,7 @@ use crate::state::*;
#[derive(Accounts)] #[derive(Accounts)]
pub struct PerpCloseMarket<'info> { pub struct PerpCloseMarket<'info> {
#[account( #[account(
constraint = group.load()?.testing == 1, constraint = group.load()?.is_testing(),
has_one = admin, has_one = admin,
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,

View File

@ -11,6 +11,7 @@ use crate::util::fill16_from_str;
pub struct PerpCreateMarket<'info> { pub struct PerpCreateMarket<'info> {
#[account( #[account(
has_one = admin, has_one = admin,
constraint = group.load()?.perps_supported()
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,
pub admin: Signer<'info>, pub admin: Signer<'info>,

View File

@ -7,7 +7,7 @@ use crate::state::*;
pub struct Serum3DeregisterMarket<'info> { pub struct Serum3DeregisterMarket<'info> {
#[account( #[account(
mut, mut,
constraint = group.load()?.testing == 1, constraint = group.load()?.is_testing(),
has_one = admin, has_one = admin,
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,

View File

@ -10,6 +10,7 @@ pub struct Serum3RegisterMarket<'info> {
#[account( #[account(
mut, mut,
has_one = admin, has_one = admin,
constraint = group.load()?.serum3_supported()
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,
pub admin: Signer<'info>, pub admin: Signer<'info>,

View File

@ -6,7 +6,7 @@ use crate::state::*;
#[derive(Accounts)] #[derive(Accounts)]
pub struct StubOracleClose<'info> { pub struct StubOracleClose<'info> {
#[account( #[account(
constraint = group.load()?.testing == 1, constraint = group.load()?.is_testing(),
has_one = admin, has_one = admin,
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,

View File

@ -11,6 +11,7 @@ use crate::state::*;
pub struct TokenAddBank<'info> { pub struct TokenAddBank<'info> {
#[account( #[account(
has_one = admin, has_one = admin,
constraint = group.load()?.multiple_banks_supported()
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,
pub admin: Signer<'info>, pub admin: Signer<'info>,

View File

@ -8,7 +8,7 @@ use anchor_lang::AccountsClose;
#[instruction(token_index: TokenIndex)] #[instruction(token_index: TokenIndex)]
pub struct TokenDeregister<'info> { pub struct TokenDeregister<'info> {
#[account( #[account(
constraint = group.load()?.testing == 1, constraint = group.load()?.is_testing(),
has_one = admin, has_one = admin,
)] )]
pub group: AccountLoader<'info, Group>, pub group: AccountLoader<'info, Group>,

View File

@ -32,8 +32,13 @@ pub mod mango_v4 {
use super::*; use super::*;
pub fn group_create(ctx: Context<GroupCreate>, group_num: u32, testing: u8) -> Result<()> { pub fn group_create(
instructions::group_create(ctx, group_num, testing) ctx: Context<GroupCreate>,
group_num: u32,
testing: u8,
version: u8,
) -> Result<()> {
instructions::group_create(ctx, group_num, testing, version)
} }
pub fn group_edit( pub fn group_edit(

View File

@ -26,15 +26,35 @@ pub struct Group {
pub insurance_mint: Pubkey, pub insurance_mint: Pubkey,
pub bump: u8, pub bump: u8,
// Only support closing/deregistering groups, stub oracles, tokens, and markets
// if testing == 1
pub testing: u8, pub testing: u8,
pub padding2: [u8; 6],
pub version: u8,
pub padding2: [u8; 5],
pub reserved: [u8; 8], pub reserved: [u8; 8],
} }
const_assert_eq!(size_of::<Group>(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 8); const_assert_eq!(size_of::<Group>(), 32 * 5 + 4 + 4 + 1 * 2 + 6 + 8);
const_assert_eq!(size_of::<Group>() % 8, 0); const_assert_eq!(size_of::<Group>() % 8, 0);
impl Group {
pub fn is_testing(&self) -> bool {
self.testing == 1
}
pub fn multiple_banks_supported(&self) -> bool {
self.is_testing() || self.version > 0
}
pub fn serum3_supported(&self) -> bool {
self.is_testing() || self.version > 0
}
pub fn perps_supported(&self) -> bool {
self.is_testing() || self.version > 0
}
}
// note: using creator instead of admin, since admin can be changed // note: using creator instead of admin, since admin can be changed
#[macro_export] #[macro_export]
macro_rules! group_seeds { macro_rules! group_seeds {

View File

@ -1230,6 +1230,7 @@ impl<'keypair> ClientInstruction for GroupCreateInstruction<'keypair> {
let instruction = Self::Instruction { let instruction = Self::Instruction {
group_num: 0, group_num: 0,
testing: 1, testing: 1,
version: 0,
}; };
let group = Pubkey::find_program_address( let group = Pubkey::find_program_address(

View File

@ -76,11 +76,12 @@ export class MangoClient {
public async groupCreate( public async groupCreate(
groupNum: number, groupNum: number,
testing: boolean, testing: boolean,
version: number,
insuranceMintPk: PublicKey, insuranceMintPk: PublicKey,
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
const adminPk = (this.program.provider as AnchorProvider).wallet.publicKey; const adminPk = (this.program.provider as AnchorProvider).wallet.publicKey;
return await this.program.methods return await this.program.methods
.groupCreate(groupNum, testing ? 1 : 0) .groupCreate(groupNum, testing ? 1 : 0, version)
.accounts({ .accounts({
creator: adminPk, creator: adminPk,
payer: adminPk, payer: adminPk,

View File

@ -41,7 +41,7 @@ export type MangoV4 = {
}, },
{ {
"name": "insuranceVault", "name": "insuranceVault",
"isMut": false, "isMut": true,
"isSigner": false, "isSigner": false,
"pda": { "pda": {
"seeds": [ "seeds": [
@ -87,6 +87,10 @@ export type MangoV4 = {
{ {
"name": "testing", "name": "testing",
"type": "u8" "type": "u8"
},
{
"name": "version",
"type": "u8"
} }
] ]
}, },
@ -2865,12 +2869,16 @@ export type MangoV4 = {
"name": "testing", "name": "testing",
"type": "u8" "type": "u8"
}, },
{
"name": "version",
"type": "u8"
},
{ {
"name": "padding2", "name": "padding2",
"type": { "type": {
"array": [ "array": [
"u8", "u8",
6 5
] ]
} }
}, },
@ -4950,7 +4958,7 @@ export const IDL: MangoV4 = {
}, },
{ {
"name": "insuranceVault", "name": "insuranceVault",
"isMut": false, "isMut": true,
"isSigner": false, "isSigner": false,
"pda": { "pda": {
"seeds": [ "seeds": [
@ -4996,6 +5004,10 @@ export const IDL: MangoV4 = {
{ {
"name": "testing", "name": "testing",
"type": "u8" "type": "u8"
},
{
"name": "version",
"type": "u8"
} }
] ]
}, },
@ -7774,12 +7786,16 @@ export const IDL: MangoV4 = {
"name": "testing", "name": "testing",
"type": "u8" "type": "u8"
}, },
{
"name": "version",
"type": "u8"
},
{ {
"name": "padding2", "name": "padding2",
"type": { "type": {
"array": [ "array": [
"u8", "u8",
6 5
] ]
} }
}, },

View File

@ -57,7 +57,7 @@ async function main() {
console.log(`Creating Group...`); console.log(`Creating Group...`);
const insuranceMint = new PublicKey(DEVNET_MINTS.get('USDC')!); const insuranceMint = new PublicKey(DEVNET_MINTS.get('USDC')!);
try { try {
await client.groupCreate(GROUP_NUM, true, insuranceMint); await client.groupCreate(GROUP_NUM, true, insuranceMint, 0);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@ -42,7 +42,7 @@ async function main() {
console.log(`Creating Group...`); console.log(`Creating Group...`);
try { try {
const insuranceMint = new PublicKey(MAINNET_MINTS.get('USDC')!); const insuranceMint = new PublicKey(MAINNET_MINTS.get('USDC')!);
await client.groupCreate(0, true, insuranceMint); await client.groupCreate(0, true, insuranceMint, 0);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }