diff --git a/Cargo.lock b/Cargo.lock index 425dd90..4ee9711 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -903,6 +903,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "const-crypto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c63acd992239f1877a7d6387038ca886a2029e41f3d91087fd454f9995f22c" +dependencies = [ + "keccak-const", + "sha2-const-stable", +] + [[package]] name = "const-oid" version = "0.7.1" @@ -1987,6 +1997,12 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-const" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" + [[package]] name = "lazy_static" version = "1.4.0" @@ -2533,6 +2549,7 @@ dependencies = [ "bs58 0.5.1", "bs64", "bytemuck", + "const-crypto", "drillx", "mpl-token-metadata", "num_enum 0.7.2", @@ -3453,6 +3470,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.9.1" diff --git a/Cargo.toml b/Cargo.toml index 3590b23..9b8ab90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,11 +21,12 @@ default = [] [dependencies] bs58 = "0.5.0" bytemuck = "1.14.3" +const-crypto = "0.1.0" drillx = { git = "https://github.com/hardhatchad/drillx", branch = "master" } mpl-token-metadata = "4.1.2" num_enum = "0.7.2" shank = "0.3.0" -solana-program = "^1.16" +solana-program = "1.18" spl-token = { version = "^4", features = ["no-entrypoint"] } spl-associated-token-account = { version = "^2.2", features = [ "no-entrypoint" ] } static_assertions = "1.1.0" @@ -34,6 +35,6 @@ thiserror = "1.0.57" [dev-dependencies] bs64 = "0.1.2" rand = "0.8.5" -solana-program-test = "^1.16" -solana-sdk = "^1.16" +solana-program-test = "^1.18" +solana-sdk = "^1.18" tokio = { version = "1.35", features = ["full"] } diff --git a/src/consts.rs b/src/consts.rs index 6680cb3..304ff1f 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,3 +1,4 @@ +use const_crypto::ed25519; use solana_program::{keccak::Hash, pubkey, pubkey::Pubkey}; /// The reward rate to intialize the program with. @@ -37,9 +38,6 @@ pub const BUS_COUNT: usize = 8; /// than a factor of this constant from one epoch to the next. pub const SMOOTHING_FACTOR: u64 = 2; -/// The range of difficulties miners can target above the minimum. -pub const DIFFICULTY_RANGE: usize = 32; - // Assert MAX_EPOCH_REWARDS is evenly divisible by BUS_COUNT. static_assertions::const_assert!( (MAX_EPOCH_REWARDS / BUS_COUNT as u64) * BUS_COUNT as u64 == MAX_EPOCH_REWARDS @@ -57,12 +55,20 @@ pub const METADATA: &[u8] = b"metadata"; /// The seed of the mint account PDA. pub const MINT: &[u8] = b"mint"; +/// The seed of the noise account PDA. +pub const NOISE: &[u8] = b"noise"; + /// The seed of proof account PDAs. pub const PROOF: &[u8] = b"proof"; /// The seed of the treasury account PDA. pub const TREASURY: &[u8] = b"treasury"; +/// Noise for deriving the mint pda +pub const MINT_NOISE: [u8; 16] = [ + 166, 199, 85, 221, 225, 119, 21, 185, 160, 82, 242, 237, 194, 84, 250, 252, +]; + /// The name for token metadata. pub const METADATA_NAME: &str = "Ore"; @@ -72,38 +78,49 @@ pub const METADATA_SYMBOL: &str = "ORE"; /// The uri for token metdata. pub const METADATA_URI: &str = "https://ore.supply/metadata.json"; -/// Noise for deriving the mint PDA. -pub const MINT_NOISE: [u8; 16] = [ - 166, 199, 85, 221, 225, 119, 21, 185, 160, 82, 242, 237, 194, 84, 250, 252, -]; +/// Program id for const pda derivations +const PROGRAM_ID: [u8; 32] = unsafe { *(&crate::id() as *const Pubkey as *const [u8; 32]) }; /// The addresses of the bus accounts. pub const BUS_ADDRESSES: [Pubkey; BUS_COUNT] = [ - pubkey!("9ShaCzHhQNvH8PLfGyrJbB8MeKHrDnuPMLnUDLJ2yMvz"), - pubkey!("4Cq8685h9GwsaD5ppPsrtfcsk3fum8f9UP4SPpKSbj2B"), - pubkey!("8L1vdGdvU3cPj9tsjJrKVUoBeXYvAzJYhExjTYHZT7h7"), - pubkey!("JBdVURCrUiHp4kr7srYtXbB7B4CwurUt1Bfxrxw6EoRY"), - pubkey!("DkmVBWJ4CLKb3pPHoSwYC2wRZXKKXLD2Ued5cGNpkWmr"), - pubkey!("9uLpj2ZCMqN6Yo1vV6yTkP6dDiTTXmeM5K3915q5CHyh"), - pubkey!("EpcfjBs8eQ4unSMdowxyTE8K3vVJ3XUnEr5BEWvSX7RB"), - pubkey!("Ay5N9vKS2Tyo2M9u9TFt59N1XbxdW93C7UrFZW3h8sMC"), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[0]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[1]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[2]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[3]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[4]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[5]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[6]], &PROGRAM_ID).0), + Pubkey::new_from_array(ed25519::derive_program_address(&[BUS, &[7]], &PROGRAM_ID).0), ]; -// TODO /// The address of the config account. -pub const CONFIG_ADDRESS: Pubkey = pubkey!("FTap9fv2GPpWGqrLj3o4c9nHH7p36ih7NbSWHnrkQYqa"); +pub const CONFIG_ADDRESS: Pubkey = + Pubkey::new_from_array(ed25519::derive_program_address(&[CONFIG], &PROGRAM_ID).0); /// The address of the mint metadata account. -pub const METADATA_ADDRESS: Pubkey = pubkey!("2nXZSxfjELuRatcoY64yHdFLZFi3mtesxobHmsoU3Dag"); - -/// The address of the mint metadata account. -pub const NOISE_ADDRESS: Pubkey = pubkey!("2nXZSxfjELuRatcoY64yHdFLZFi3mtesxobHmsoU3Dag"); +pub const METADATA_ADDRESS: Pubkey = Pubkey::new_from_array( + ed25519::derive_program_address( + &[ + METADATA, + unsafe { &*(&mpl_token_metadata::ID as *const Pubkey as *const [u8; 32]) }, + unsafe { &*(&MINT_ADDRESS as *const Pubkey as *const [u8; 32]) }, + ], + unsafe { &*(&mpl_token_metadata::ID as *const Pubkey as *const [u8; 32]) }, + ) + .0, +); /// The address of the mint account. -pub const MINT_ADDRESS: Pubkey = pubkey!("oreoN2tQbHXVaZsr3pf66A48miqcBXCDJozganhEJgz"); +pub const MINT_ADDRESS: Pubkey = + Pubkey::new_from_array(ed25519::derive_program_address(&[MINT, &MINT_NOISE], &PROGRAM_ID).0); -/// The address of the mint account. +/// The address of the v1 mint account. pub const MINT_V1_ADDRESS: Pubkey = pubkey!("oreoN2tQbHXVaZsr3pf66A48miqcBXCDJozganhEJgz"); +/// The address of the mint metadata account. +pub const NOISE_ADDRESS: Pubkey = + Pubkey::new_from_array(ed25519::derive_program_address(&[NOISE], &PROGRAM_ID).0); + /// The address of the treasury account. -pub const TREASURY_ADDRESS: Pubkey = pubkey!("FTap9fv2GPpWGqrLj3o4c9nHH7p36ih7NbSWHnrkQYqa"); +pub const TREASURY_ADDRESS: Pubkey = + Pubkey::new_from_array(ed25519::derive_program_address(&[TREASURY], &PROGRAM_ID).0); diff --git a/src/instruction.rs b/src/instruction.rs index 5e49e49..349b4a3 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -8,8 +8,8 @@ use solana_program::{ }; use crate::{ - impl_instruction_from_bytes, impl_to_bytes, BUS, CONFIG, CONFIG_ADDRESS, METADATA, MINT, - MINT_ADDRESS, MINT_NOISE, PROOF, TREASURY, TREASURY_ADDRESS, + impl_instruction_from_bytes, impl_to_bytes, BUS, BUS_ADDRESSES, CONFIG, CONFIG_ADDRESS, + METADATA, MINT, MINT_ADDRESS, MINT_NOISE, PROOF, TREASURY, TREASURY_ADDRESS, }; #[repr(u8)] @@ -177,14 +177,6 @@ impl_instruction_from_bytes!(UpdateAdminArgs); /// Builds a reset instruction. pub fn reset(signer: Pubkey) -> Instruction { - let bus_0 = Pubkey::find_program_address(&[BUS, &[0]], &crate::id()).0; - let bus_1 = Pubkey::find_program_address(&[BUS, &[1]], &crate::id()).0; - let bus_2 = Pubkey::find_program_address(&[BUS, &[2]], &crate::id()).0; - let bus_3 = Pubkey::find_program_address(&[BUS, &[3]], &crate::id()).0; - let bus_4 = Pubkey::find_program_address(&[BUS, &[4]], &crate::id()).0; - let bus_5 = Pubkey::find_program_address(&[BUS, &[5]], &crate::id()).0; - let bus_6 = Pubkey::find_program_address(&[BUS, &[6]], &crate::id()).0; - let bus_7 = Pubkey::find_program_address(&[BUS, &[7]], &crate::id()).0; let treasury_tokens = spl_associated_token_account::get_associated_token_address( &TREASURY_ADDRESS, &MINT_ADDRESS, @@ -193,14 +185,14 @@ pub fn reset(signer: Pubkey) -> Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), - AccountMeta::new(bus_0, false), - AccountMeta::new(bus_1, false), - AccountMeta::new(bus_2, false), - AccountMeta::new(bus_3, false), - AccountMeta::new(bus_4, false), - AccountMeta::new(bus_5, false), - AccountMeta::new(bus_6, false), - AccountMeta::new(bus_7, false), + AccountMeta::new(BUS_ADDRESSES[0], false), + AccountMeta::new(BUS_ADDRESSES[1], false), + AccountMeta::new(BUS_ADDRESSES[2], false), + AccountMeta::new(BUS_ADDRESSES[3], false), + AccountMeta::new(BUS_ADDRESSES[4], false), + AccountMeta::new(BUS_ADDRESSES[5], false), + AccountMeta::new(BUS_ADDRESSES[6], false), + AccountMeta::new(BUS_ADDRESSES[7], false), AccountMeta::new(MINT_ADDRESS, false), AccountMeta::new(TREASURY_ADDRESS, false), AccountMeta::new(treasury_tokens, false), diff --git a/src/lib.rs b/src/lib.rs index c31df80..dc85594 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,8 +14,7 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, }; -// TODO Upgrade (v1 to v2 token) -// TODO Downgrade (v2 to v1 token) +// TODO Is downgrade necessary or no? declare_id!("mineRHF5r6S7HyD9SppBfVMXMavDkJsxwGesEvxZr2A"); diff --git a/src/processor/mine.rs b/src/processor/mine.rs index 0fb38ab..daf02fa 100644 --- a/src/processor/mine.rs +++ b/src/processor/mine.rs @@ -17,7 +17,7 @@ use crate::{ loaders::*, state::{Bus, Config, Proof}, utils::AccountDeserialize, - DIFFICULTY_RANGE, EPOCH_DURATION, + EPOCH_DURATION, }; // TODO Look into tx introspection to require 1 hash per tx @@ -89,9 +89,7 @@ pub fn process_mine<'a, 'info>( } // Calculate base reward rate - let difficulty = difficulty - .saturating_sub(config.min_difficulty) - .min(DIFFICULTY_RANGE as u32); + let difficulty = difficulty.saturating_sub(config.min_difficulty); let mut reward = config .base_reward_rate .saturating_mul(2u64.saturating_pow(difficulty)); @@ -131,6 +129,7 @@ pub fn process_mine<'a, 'info>( } // Update balances + // TODO Handle case where reward is higher than bus can payout let mut bus_data = bus_info.data.borrow_mut(); let bus = Bus::try_from_bytes_mut(&mut bus_data)?; bus.rewards = bus diff --git a/src/state/hash.rs b/src/state/hash.rs index dd19e38..55084de 100644 --- a/src/state/hash.rs +++ b/src/state/hash.rs @@ -30,18 +30,18 @@ impl fmt::Display for Hash { } } -impl Hash { - pub fn difficulty(&self) -> u32 { - let mut count = 0; - for &byte in &self.0 { - let lz = byte.leading_zeros(); - count += lz; - if lz < 8 { - break; - } - } - count - } -} +// impl Hash { +// pub fn difficulty(&self) -> u32 { +// let mut count = 0; +// for &byte in &self.0 { +// let lz = byte.leading_zeros(); +// count += lz; +// if lz < 8 { +// break; +// } +// } +// count +// } +// } impl_to_bytes!(Hash);