Add Confidential Transfer Extension boilerplate
This commit is contained in:
parent
0a98473f0a
commit
5fe1eb6a9d
|
@ -27,6 +27,42 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-gcm-siv"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"aes",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"polyval",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.4.7"
|
||||
|
@ -425,6 +461,15 @@ dependencies = [
|
|||
"chrono",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
|
@ -607,6 +652,15 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "3.2.0"
|
||||
|
@ -616,6 +670,7 @@ dependencies = [
|
|||
"byteorder",
|
||||
"digest",
|
||||
"rand_core 0.5.1",
|
||||
"serde",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
@ -1570,6 +1625,18 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "merlin"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"keccak",
|
||||
"rand_core 0.5.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metaplex-token-metadata"
|
||||
version = "0.0.1"
|
||||
|
@ -1913,6 +1980,18 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
|
@ -3310,6 +3389,36 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-zk-token-sdk"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2243307ab81fedd2f7e3b4b2b541ab0314cc4a26aebbf7ed6ddb839808cb244"
|
||||
dependencies = [
|
||||
"aes-gcm-siv",
|
||||
"arrayref",
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"cipher",
|
||||
"curve25519-dalek",
|
||||
"getrandom 0.1.16",
|
||||
"lazy_static",
|
||||
"merlin",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha3",
|
||||
"solana-program",
|
||||
"solana-sdk",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.2.19"
|
||||
|
@ -3706,6 +3815,7 @@ dependencies = [
|
|||
"solana-program",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
"solana-zk-token-sdk",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -4309,6 +4419,16 @@ version = "0.1.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
|
@ -4567,9 +4687,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.4.3"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
|
||||
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
|
|
@ -19,6 +19,7 @@ num-derive = "0.3"
|
|||
num-traits = "0.2"
|
||||
num_enum = "0.5.4"
|
||||
solana-program = "1.9.2"
|
||||
solana-zk-token-sdk = "0.1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
use {
|
||||
crate::{id, instruction::TokenInstruction, pod::*},
|
||||
bytemuck::Pod,
|
||||
num_derive::{FromPrimitive, ToPrimitive},
|
||||
num_traits::{FromPrimitive, ToPrimitive},
|
||||
solana_program::{
|
||||
instruction::{AccountMeta, Instruction},
|
||||
program_error::ProgramError,
|
||||
},
|
||||
};
|
||||
|
||||
/// Confidential Transfer extension instructions
|
||||
#[derive(Clone, Copy, Debug, FromPrimitive, ToPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum ConfidentialTransferInstruction {
|
||||
/// TODO: inline `zk_token_program::instructions::ZkTokenInstruction` here
|
||||
Todo,
|
||||
}
|
||||
|
||||
pub(crate) fn decode_instruction_type(
|
||||
input: &[u8],
|
||||
) -> Result<ConfidentialTransferInstruction, ProgramError> {
|
||||
if input.is_empty() {
|
||||
Err(ProgramError::InvalidInstructionData)
|
||||
} else {
|
||||
FromPrimitive::from_u8(input[0]).ok_or(ProgramError::InvalidInstructionData)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decode_instruction_data<T: Pod>(input: &[u8]) -> Result<&T, ProgramError> {
|
||||
if input.is_empty() {
|
||||
Err(ProgramError::InvalidInstructionData)
|
||||
} else {
|
||||
pod_from_bytes(&input[1..])
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_instruction<T: Pod>(
|
||||
accounts: Vec<AccountMeta>,
|
||||
instruction_type: ConfidentialTransferInstruction,
|
||||
instruction_data: &T,
|
||||
) -> Instruction {
|
||||
let mut data = TokenInstruction::ConfidentialTransferExtension.pack();
|
||||
data.push(ToPrimitive::to_u8(&instruction_type).unwrap());
|
||||
data.extend_from_slice(bytemuck::bytes_of(instruction_data));
|
||||
Instruction {
|
||||
program_id: id(),
|
||||
accounts,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a `Todo` instruction
|
||||
pub fn todo() -> Instruction {
|
||||
encode_instruction(vec![], ConfidentialTransferInstruction::Todo, &())
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
use {
|
||||
crate::extension::{AccountType, Extension, ExtensionType},
|
||||
bytemuck::{Pod, Zeroable},
|
||||
};
|
||||
|
||||
/// Confidential Transfer Extension instructions
|
||||
pub mod instruction;
|
||||
|
||||
/// Confidential Transfer Extension processor
|
||||
pub mod processor;
|
||||
|
||||
/// Transfer auditor configuration
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
||||
pub struct MintConfidentialTransferAuditor {
|
||||
// TODO: inline `zk_token_program::state::Auditor` here
|
||||
}
|
||||
|
||||
impl Extension for MintConfidentialTransferAuditor {
|
||||
const TYPE: ExtensionType = ExtensionType::MintConfidentialTransferAuditor;
|
||||
const ACCOUNT_TYPE: AccountType = AccountType::Mint;
|
||||
}
|
||||
|
||||
/// Confidential account state
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
||||
pub struct AccountConfidentialState {
|
||||
// TODO: inline `zk_token_program::state::ZkAccount` here
|
||||
}
|
||||
|
||||
impl Extension for AccountConfidentialState {
|
||||
const TYPE: ExtensionType = ExtensionType::AccountConfidentialState;
|
||||
const ACCOUNT_TYPE: AccountType = AccountType::Account;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
use {
|
||||
super::instruction::*,
|
||||
solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey},
|
||||
};
|
||||
|
||||
/// TODO: inline `zk_token_program::processor.rs` here
|
||||
pub fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
_accounts: &[AccountInfo],
|
||||
input: &[u8],
|
||||
) -> ProgramResult {
|
||||
match decode_instruction_type(input)? {
|
||||
ConfidentialTransferInstruction::Todo => {
|
||||
let todo_data = decode_instruction_data::<()>(input)?;
|
||||
msg!("Todo: {:?}", todo_data);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
use {
|
||||
crate::{
|
||||
extension::{
|
||||
confidential_transfer::{AccountConfidentialState, MintConfidentialTransferAuditor},
|
||||
mint_close_authority::MintCloseAuthority,
|
||||
transfer_fee::{AccountTransferFee, MintTransferFee},
|
||||
},
|
||||
|
@ -21,8 +22,12 @@ use {
|
|||
},
|
||||
};
|
||||
|
||||
mod mint_close_authority;
|
||||
mod transfer_fee;
|
||||
/// Confidential Transfer extension
|
||||
pub mod confidential_transfer;
|
||||
/// Mint Close Authority extension
|
||||
pub mod mint_close_authority;
|
||||
/// Transfer Fee extension
|
||||
pub mod transfer_fee;
|
||||
|
||||
/// Length in TLV structure
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
|
||||
|
@ -332,6 +337,10 @@ pub enum ExtensionType {
|
|||
AccountTransferFee,
|
||||
/// Includes an optional mint close authority
|
||||
MintCloseAuthority,
|
||||
/// Auditor configuration for confidential transfers
|
||||
MintConfidentialTransferAuditor,
|
||||
/// Confidential Account state
|
||||
AccountConfidentialState,
|
||||
/// Padding extension used to make an account exactly Multisig::LEN, used for testing
|
||||
#[cfg(test)]
|
||||
AccountPaddingTest = u16::MAX - 1,
|
||||
|
@ -361,6 +370,12 @@ impl ExtensionType {
|
|||
ExtensionType::MintTransferFee => pod_get_packed_len::<MintTransferFee>(),
|
||||
ExtensionType::AccountTransferFee => pod_get_packed_len::<AccountTransferFee>(),
|
||||
ExtensionType::MintCloseAuthority => pod_get_packed_len::<MintCloseAuthority>(),
|
||||
ExtensionType::MintConfidentialTransferAuditor => {
|
||||
pod_get_packed_len::<MintConfidentialTransferAuditor>()
|
||||
}
|
||||
ExtensionType::AccountConfidentialState => {
|
||||
pod_get_packed_len::<AccountConfidentialState>()
|
||||
}
|
||||
#[cfg(test)]
|
||||
ExtensionType::AccountPaddingTest => pod_get_packed_len::<AccountPaddingTest>(),
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -569,6 +569,12 @@ pub enum TokenInstruction {
|
|||
/// Maximum fee assessed on transfers
|
||||
maximum_fee: u64,
|
||||
},
|
||||
|
||||
/// The common instruction prefix for Confidential Transfer extension instructions.
|
||||
///
|
||||
/// See `extension::confidential_transfer::instruction::ConfidentialTransferInstruction` for
|
||||
/// further details about the extended instructions that share this instruction prefix
|
||||
ConfidentialTransferExtension,
|
||||
}
|
||||
impl TokenInstruction {
|
||||
/// Unpacks a byte buffer into a [TokenInstruction](enum.TokenInstruction.html).
|
||||
|
@ -755,6 +761,7 @@ impl TokenInstruction {
|
|||
maximum_fee,
|
||||
}
|
||||
}
|
||||
29 => Self::ConfidentialTransferExtension,
|
||||
_ => return Err(TokenError::InvalidInstruction.into()),
|
||||
})
|
||||
}
|
||||
|
@ -900,6 +907,9 @@ impl TokenInstruction {
|
|||
buf.extend_from_slice(&transfer_fee_basis_points.to_le_bytes());
|
||||
buf.extend_from_slice(&maximum_fee.to_le_bytes());
|
||||
}
|
||||
&Self::ConfidentialTransferExtension => {
|
||||
buf.push(29);
|
||||
}
|
||||
};
|
||||
buf
|
||||
}
|
||||
|
|
|
@ -851,6 +851,13 @@ impl Processor {
|
|||
TokenInstruction::SetTransferFee { .. } => {
|
||||
unimplemented!();
|
||||
}
|
||||
TokenInstruction::ConfidentialTransferExtension => {
|
||||
crate::extension::confidential_transfer::processor::process_instruction(
|
||||
program_id,
|
||||
accounts,
|
||||
&input[1..],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue