mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-02 22:33:37 +00:00
fix: intercommit
This commit is contained in:
parent
d4a471e948
commit
b3dca76b67
@ -1,3 +1,4 @@
|
|||||||
|
use nssa::AccountId;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::rpc_primitives::errors::RpcError;
|
use crate::rpc_primitives::errors::RpcError;
|
||||||
@ -49,4 +50,6 @@ pub enum ExecutionFailureKind {
|
|||||||
SequencerClientError(#[from] SequencerClientError),
|
SequencerClientError(#[from] SequencerClientError),
|
||||||
#[error("Can not pay for operation")]
|
#[error("Can not pay for operation")]
|
||||||
InsufficientFundsError,
|
InsufficientFundsError,
|
||||||
|
#[error("Account {0} data is invalid")]
|
||||||
|
AccountDataError(AccountId),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,8 +23,8 @@ use wallet::{
|
|||||||
account::{AccountSubcommand, NewSubcommand},
|
account::{AccountSubcommand, NewSubcommand},
|
||||||
config::ConfigSubcommand,
|
config::ConfigSubcommand,
|
||||||
programs::{
|
programs::{
|
||||||
native_token_transfer::AuthTransferSubcommand, pinata::PinataProgramAgnosticSubcommand,
|
amm::AmmProgramAgnosticSubcommand, native_token_transfer::AuthTransferSubcommand,
|
||||||
token::TokenProgramAgnosticSubcommand,
|
pinata::PinataProgramAgnosticSubcommand, token::TokenProgramAgnosticSubcommand,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config::PersistentStorage,
|
config::PersistentStorage,
|
||||||
@ -2035,6 +2035,198 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
|||||||
info!("Success!");
|
info!("Success!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[nssa_integration_test]
|
||||||
|
pub async fn test_amm_public() {
|
||||||
|
info!("########## test_amm_public ##########");
|
||||||
|
let wallet_config = fetch_config().await.unwrap();
|
||||||
|
|
||||||
|
// Create new account for the token definition
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: definition_account_id,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for the token supply holder
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: supply_account_id,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for receiving a token transaction
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: recipient_account_id_1,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for receiving a token transaction
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: recipient_account_id_2,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create new token
|
||||||
|
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||||
|
definition_account_id: make_public_account_input_from_str(
|
||||||
|
&definition_account_id.to_string(),
|
||||||
|
),
|
||||||
|
supply_account_id: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||||
|
name: "A NAME".to_string(),
|
||||||
|
total_supply: 37,
|
||||||
|
};
|
||||||
|
wallet::cli::execute_subcommand(Command::Token(subcommand))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||||
|
|
||||||
|
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
|
||||||
|
|
||||||
|
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_1`
|
||||||
|
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||||
|
from: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||||
|
to: Some(make_public_account_input_from_str(
|
||||||
|
&recipient_account_id_1.to_string(),
|
||||||
|
)),
|
||||||
|
to_npk: None,
|
||||||
|
to_ipk: None,
|
||||||
|
amount: 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
wallet::cli::execute_subcommand(Command::Token(subcommand))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||||
|
|
||||||
|
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_2`
|
||||||
|
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||||
|
from: make_public_account_input_from_str(&supply_account_id.to_string()),
|
||||||
|
to: Some(make_public_account_input_from_str(
|
||||||
|
&recipient_account_id_2.to_string(),
|
||||||
|
)),
|
||||||
|
to_npk: None,
|
||||||
|
to_ipk: None,
|
||||||
|
amount: 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
wallet::cli::execute_subcommand(Command::Token(subcommand))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||||
|
|
||||||
|
info!("=================== SETUP FINISHED ===============");
|
||||||
|
|
||||||
|
// Create new AMM
|
||||||
|
|
||||||
|
// Setup accounts
|
||||||
|
// Create new account for the amm pool
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: amm_pool,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for the vault a
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: vault_holding_a,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for the vault b
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: vault_holding_b,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for the pool lp
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: pool_lp,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
// Create new account for the user holding lp
|
||||||
|
let SubcommandReturnValue::RegisterAccount {
|
||||||
|
account_id: user_holding_lp,
|
||||||
|
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
|
||||||
|
NewSubcommand::Public { cci: None },
|
||||||
|
)))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
else {
|
||||||
|
panic!("invalid subcommand return value");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send creation tx
|
||||||
|
let subcommand = AmmProgramAgnosticSubcommand::New {
|
||||||
|
amm_pool: make_public_account_input_from_str(&amm_pool.to_string()),
|
||||||
|
vault_holding_a: make_public_account_input_from_str(&vault_holding_a.to_string()),
|
||||||
|
vault_holding_b: make_public_account_input_from_str(&vault_holding_b.to_string()),
|
||||||
|
pool_lp: make_public_account_input_from_str(&pool_lp.to_string()),
|
||||||
|
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||||
|
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||||
|
user_holding_lp: make_public_account_input_from_str(&user_holding_lp.to_string()),
|
||||||
|
balance_a: 3,
|
||||||
|
balance_b: 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
wallet::cli::execute_subcommand(Command::AMM(subcommand))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||||
|
|
||||||
|
let amm_pool_acc = seq_client
|
||||||
|
.get_account(amm_pool.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.account;
|
||||||
|
|
||||||
|
info!("AMM pool is {amm_pool_acc:#?}");
|
||||||
|
|
||||||
|
info!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
println!("{function_map:#?}");
|
println!("{function_map:#?}");
|
||||||
|
|
||||||
function_map
|
function_map
|
||||||
|
|||||||
@ -124,6 +124,7 @@ pub struct ProgramOutput {
|
|||||||
pub fn read_nssa_inputs<T: DeserializeOwned>() -> (ProgramInput<T>, InstructionData) {
|
pub fn read_nssa_inputs<T: DeserializeOwned>() -> (ProgramInput<T>, InstructionData) {
|
||||||
let pre_states: Vec<AccountWithMetadata> = env::read();
|
let pre_states: Vec<AccountWithMetadata> = env::read();
|
||||||
let instruction_words: InstructionData = env::read();
|
let instruction_words: InstructionData = env::read();
|
||||||
|
println!("INSTRUCTION WORKDS IS {instruction_words:?}");
|
||||||
let instruction = T::deserialize(&mut Deserializer::new(instruction_words.as_ref())).unwrap();
|
let instruction = T::deserialize(&mut Deserializer::new(instruction_words.as_ref())).unwrap();
|
||||||
(
|
(
|
||||||
ProgramInput {
|
ProgramInput {
|
||||||
|
|||||||
@ -55,7 +55,6 @@ use nssa_core::{
|
|||||||
// * compute_pool_pda_seed: token definitions for the pool pair
|
// * compute_pool_pda_seed: token definitions for the pool pair
|
||||||
// * compute_vault_pda_seed: pool definition id, definition token id,
|
// * compute_vault_pda_seed: pool definition id, definition token id,
|
||||||
// * compute_liquidity_token_pda_seed: pool definition id
|
// * compute_liquidity_token_pda_seed: pool definition id
|
||||||
//
|
|
||||||
|
|
||||||
const POOL_DEFINITION_DATA_SIZE: usize = 225;
|
const POOL_DEFINITION_DATA_SIZE: usize = 225;
|
||||||
|
|
||||||
|
|||||||
@ -30,4 +30,18 @@ impl Message {
|
|||||||
instruction_data,
|
instruction_data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_preserialized(
|
||||||
|
program_id: ProgramId,
|
||||||
|
account_ids: Vec<AccountId>,
|
||||||
|
nonces: Vec<Nonce>,
|
||||||
|
instruction_data: Vec<u32>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
program_id,
|
||||||
|
account_ids,
|
||||||
|
nonces,
|
||||||
|
instruction_data,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,10 @@ struct TokenDefinition {
|
|||||||
total_supply: u128,
|
total_supply: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TokenHolding {
|
pub struct TokenHolding {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
account_type: u8,
|
account_type: u8,
|
||||||
definition_id: AccountId,
|
pub definition_id: AccountId,
|
||||||
balance: u128,
|
balance: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ impl TokenDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TokenHolding {
|
impl TokenHolding {
|
||||||
fn parse(data: &[u8]) -> Option<Self> {
|
pub fn parse(data: &[u8]) -> Option<Self> {
|
||||||
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
|
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,30 +1,43 @@
|
|||||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||||
use nssa::{AccountId, program::Program};
|
use nssa::{AccountId, program::Program};
|
||||||
use nssa_core::{SharedSecretKey, program::InstructionData};
|
use nssa_core::{SharedSecretKey, program::InstructionData};
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
use crate::{PrivacyPreservingAccount, WalletCore, cli::account::TokenHolding};
|
||||||
|
|
||||||
struct OrphanHack65BytesInput([u8; 65]);
|
struct OrphanHack65BytesInput([u32; 65]);
|
||||||
|
|
||||||
impl Serialize for OrphanHack65BytesInput {
|
impl OrphanHack65BytesInput {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn expand(orig: [u8; 65]) -> Self {
|
||||||
where
|
let mut res = [0u32; 65];
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
for (idx, val) in orig.into_iter().enumerate() {
|
||||||
serializer.serialize_bytes(&self.0)
|
res[idx] = val as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn words(&self) -> Vec<u32> {
|
||||||
|
self.0.to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OrphanHack49BytesInput([u8; 49]);
|
struct OrphanHack49BytesInput([u32; 49]);
|
||||||
|
|
||||||
impl Serialize for OrphanHack49BytesInput {
|
impl OrphanHack49BytesInput {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn expand(orig: [u8; 49]) -> Self {
|
||||||
where
|
let mut res = [0u32; 49];
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
for (idx, val) in orig.into_iter().enumerate() {
|
||||||
serializer.serialize_bytes(&self.0)
|
res[idx] = val as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn words(&self) -> Vec<u32> {
|
||||||
|
self.0.to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AMM<'w>(pub &'w WalletCore);
|
pub struct AMM<'w>(pub &'w WalletCore);
|
||||||
@ -33,17 +46,91 @@ impl AMM<'_> {
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn send_new_amm_definition(
|
pub async fn send_new_amm_definition(
|
||||||
&self,
|
&self,
|
||||||
_amm_pool: PrivacyPreservingAccount,
|
amm_pool: PrivacyPreservingAccount,
|
||||||
_vault_holding_a: PrivacyPreservingAccount,
|
vault_holding_a: PrivacyPreservingAccount,
|
||||||
_vault_holding_b: PrivacyPreservingAccount,
|
vault_holding_b: PrivacyPreservingAccount,
|
||||||
_pool_lp: PrivacyPreservingAccount,
|
pool_lp: PrivacyPreservingAccount,
|
||||||
_user_holding_a: PrivacyPreservingAccount,
|
user_holding_a: PrivacyPreservingAccount,
|
||||||
_user_holding_b: PrivacyPreservingAccount,
|
user_holding_b: PrivacyPreservingAccount,
|
||||||
_user_holding_lp: PrivacyPreservingAccount,
|
user_holding_lp: PrivacyPreservingAccount,
|
||||||
_balance_a: u128,
|
balance_a: u128,
|
||||||
_balance_b: u128,
|
balance_b: u128,
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
todo!()
|
let (instruction, program) = amm_program_preparation_definition(balance_a, balance_b);
|
||||||
|
|
||||||
|
match (
|
||||||
|
amm_pool,
|
||||||
|
vault_holding_a,
|
||||||
|
vault_holding_b,
|
||||||
|
pool_lp,
|
||||||
|
user_holding_a,
|
||||||
|
user_holding_b,
|
||||||
|
user_holding_lp,
|
||||||
|
) {
|
||||||
|
(
|
||||||
|
PrivacyPreservingAccount::Public(amm_pool),
|
||||||
|
PrivacyPreservingAccount::Public(vault_holding_a),
|
||||||
|
PrivacyPreservingAccount::Public(vault_holding_b),
|
||||||
|
PrivacyPreservingAccount::Public(pool_lp),
|
||||||
|
PrivacyPreservingAccount::Public(user_holding_a),
|
||||||
|
PrivacyPreservingAccount::Public(user_holding_b),
|
||||||
|
PrivacyPreservingAccount::Public(user_holding_lp),
|
||||||
|
) => {
|
||||||
|
let account_ids = vec![
|
||||||
|
amm_pool,
|
||||||
|
vault_holding_a,
|
||||||
|
vault_holding_b,
|
||||||
|
pool_lp,
|
||||||
|
user_holding_a,
|
||||||
|
user_holding_b,
|
||||||
|
user_holding_lp,
|
||||||
|
];
|
||||||
|
|
||||||
|
let Ok(nonces) = self
|
||||||
|
.0
|
||||||
|
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||||
|
.await
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_a) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_a)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_b) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_b)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
|
program.id(),
|
||||||
|
account_ids,
|
||||||
|
nonces,
|
||||||
|
instruction,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||||
|
&message,
|
||||||
|
&[signing_key_a, signing_key_b],
|
||||||
|
);
|
||||||
|
|
||||||
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@ -99,18 +186,55 @@ impl AMM<'_> {
|
|||||||
user_holding_b,
|
user_holding_b,
|
||||||
];
|
];
|
||||||
|
|
||||||
// ToDo: Correct authorization
|
let account_id_auth;
|
||||||
// ToDo: Also correct instruction serialization
|
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
// Checking, which account are associated with TokenDefinition
|
||||||
|
let token_holder_acc_a = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_a)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
let token_holder_acc_b = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_b)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
|
let token_holder_a = TokenHolding::parse(&token_holder_acc_a.data)
|
||||||
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?;
|
||||||
|
let token_holder_b = TokenHolding::parse(&token_holder_acc_b.data)
|
||||||
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_b))?;
|
||||||
|
|
||||||
|
if token_holder_a.definition_id == token_definition_id {
|
||||||
|
account_id_auth = user_holding_a;
|
||||||
|
} else if token_holder_b.definition_id == token_definition_id {
|
||||||
|
account_id_auth = user_holding_b;
|
||||||
|
} else {
|
||||||
|
return Err(ExecutionFailureKind::AccountDataError(token_definition_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
let Ok(nonces) = self.0.get_accounts_nonces(vec![account_id_auth]).await else {
|
||||||
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&account_id_auth)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let message = nssa::public_transaction::Message::new_preserialized(
|
||||||
program.id(),
|
program.id(),
|
||||||
account_ids,
|
account_ids,
|
||||||
vec![],
|
nonces,
|
||||||
instruction,
|
instruction,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
let witness_set =
|
||||||
|
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||||
|
|
||||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
@ -218,18 +342,44 @@ impl AMM<'_> {
|
|||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
];
|
];
|
||||||
|
|
||||||
// ToDo: Correct authorization
|
let Ok(nonces) = self
|
||||||
// ToDo: Also correct instruction serialization
|
.0
|
||||||
|
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||||
|
.await
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_a) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_a)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_b) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_b)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
account_ids,
|
account_ids,
|
||||||
vec![],
|
nonces,
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||||
|
&message,
|
||||||
|
&[signing_key_a, signing_key_b],
|
||||||
|
);
|
||||||
|
|
||||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
@ -343,18 +493,44 @@ impl AMM<'_> {
|
|||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
];
|
];
|
||||||
|
|
||||||
// ToDo: Correct authorization
|
let Ok(nonces) = self
|
||||||
// ToDo: Also correct instruction serialization
|
.0
|
||||||
|
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||||
|
.await
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_a) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_a)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(signing_key_b) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&user_holding_b)
|
||||||
|
else {
|
||||||
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
|
};
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
account_ids,
|
account_ids,
|
||||||
vec![],
|
nonces,
|
||||||
instruction,
|
instruction,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||||
|
&message,
|
||||||
|
&[signing_key_a, signing_key_b],
|
||||||
|
);
|
||||||
|
|
||||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
@ -431,7 +607,7 @@ fn amm_program_preparation_definition(
|
|||||||
) -> (InstructionData, Program) {
|
) -> (InstructionData, Program) {
|
||||||
// An instruction data of 65-bytes, indicating the initial amm reserves' balances and
|
// An instruction data of 65-bytes, indicating the initial amm reserves' balances and
|
||||||
// token_program_id with the following layout:
|
// token_program_id with the following layout:
|
||||||
// [0x00 || array of balances (little-endian 16 bytes) || AMM_PROGRAM_ID)]
|
// [0x00 || array of balances (little-endian 16 bytes) || TOKEN_PROGRAM_ID)]
|
||||||
let amm_program_id = Program::token().id();
|
let amm_program_id = Program::token().id();
|
||||||
|
|
||||||
let mut instruction = [0; 65];
|
let mut instruction = [0; 65];
|
||||||
@ -448,9 +624,8 @@ fn amm_program_preparation_definition(
|
|||||||
instruction[57..61].copy_from_slice(&amm_program_id[6].to_le_bytes());
|
instruction[57..61].copy_from_slice(&amm_program_id[6].to_le_bytes());
|
||||||
instruction[61..].copy_from_slice(&amm_program_id[7].to_le_bytes());
|
instruction[61..].copy_from_slice(&amm_program_id[7].to_le_bytes());
|
||||||
|
|
||||||
let instruction_data =
|
let instruction_data = OrphanHack65BytesInput::expand(instruction).words();
|
||||||
Program::serialize_instruction(OrphanHack65BytesInput(instruction)).unwrap();
|
let program = Program::amm();
|
||||||
let program = Program::token();
|
|
||||||
|
|
||||||
(instruction_data, program)
|
(instruction_data, program)
|
||||||
}
|
}
|
||||||
@ -471,8 +646,8 @@ fn amm_program_preparation_swap(
|
|||||||
instruction[33..].copy_from_slice(&token_definition_id.to_bytes());
|
instruction[33..].copy_from_slice(&token_definition_id.to_bytes());
|
||||||
|
|
||||||
let instruction_data =
|
let instruction_data =
|
||||||
Program::serialize_instruction(OrphanHack65BytesInput(instruction)).unwrap();
|
OrphanHack65BytesInput::expand(instruction).words();
|
||||||
let program = Program::token();
|
let program = Program::amm();
|
||||||
|
|
||||||
(instruction_data, program)
|
(instruction_data, program)
|
||||||
}
|
}
|
||||||
@ -492,9 +667,8 @@ fn amm_program_preparation_add_liq(
|
|||||||
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
||||||
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
||||||
|
|
||||||
let instruction_data =
|
let instruction_data = OrphanHack49BytesInput::expand(instruction).words();
|
||||||
Program::serialize_instruction(OrphanHack49BytesInput(instruction)).unwrap();
|
let program = Program::amm();
|
||||||
let program = Program::token();
|
|
||||||
|
|
||||||
(instruction_data, program)
|
(instruction_data, program)
|
||||||
}
|
}
|
||||||
@ -514,9 +688,30 @@ fn amm_program_preparation_remove_liq(
|
|||||||
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
instruction[17..33].copy_from_slice(&max_amount_a.to_le_bytes());
|
||||||
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
instruction[33..49].copy_from_slice(&max_amount_b.to_le_bytes());
|
||||||
|
|
||||||
let instruction_data =
|
let instruction_data = OrphanHack49BytesInput::expand(instruction).words();
|
||||||
Program::serialize_instruction(OrphanHack49BytesInput(instruction)).unwrap();
|
let program = Program::amm();
|
||||||
let program = Program::token();
|
|
||||||
|
|
||||||
(instruction_data, program)
|
(instruction_data, program)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::program_facades::amm::OrphanHack65BytesInput;
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_correct_ser() {
|
||||||
|
let mut arr = [0u8; 65];
|
||||||
|
|
||||||
|
for i in 0..64 {
|
||||||
|
arr[i] = i as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hack = OrphanHack65BytesInput::expand(arr);
|
||||||
|
let instruction_data = hack.words();
|
||||||
|
|
||||||
|
println!("{instruction_data:?}");
|
||||||
|
|
||||||
|
//assert_eq!(serialization_res_1, serialization_res_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user