mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-08 00:03:09 +00:00
add integratin tests wip
This commit is contained in:
parent
5979d8d0cf
commit
473a5fd98b
@ -172,6 +172,47 @@ pub async fn test_success_move_to_another_account() {
|
||||
info!("Success!");
|
||||
}
|
||||
|
||||
pub async fn test_success_token_program() {
|
||||
let wallet_config = fetch_config().unwrap();
|
||||
|
||||
wallet::execute_subcommand(Command::RegisterAccount {})
|
||||
.await
|
||||
.unwrap();
|
||||
wallet::execute_subcommand(Command::RegisterAccount {})
|
||||
.await
|
||||
.unwrap();
|
||||
wallet::execute_subcommand(Command::RegisterAccount {})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let persistent_accounts = fetch_persistent_accounts().unwrap();
|
||||
|
||||
let mut new_persistent_accounts_addr = Vec::new();
|
||||
|
||||
for per_acc in persistent_accounts {
|
||||
if (per_acc.address.to_string() != ACC_RECEIVER)
|
||||
&& (per_acc.address.to_string() != ACC_SENDER)
|
||||
{
|
||||
new_persistent_accounts_addr.push(per_acc.address.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let [definition_addr, supply_addr, other_addr] = new_persistent_accounts_addr
|
||||
.try_into()
|
||||
.expect("Failed to produce new account, not present in persistent accounts");
|
||||
|
||||
let command = Command::NewTokenDefinition {
|
||||
definition_addr,
|
||||
supply_addr,
|
||||
name: "name".to_string(),
|
||||
total_supply: 37,
|
||||
};
|
||||
|
||||
wallet::execute_subcommand(command).await.unwrap();
|
||||
|
||||
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
|
||||
}
|
||||
|
||||
pub async fn test_failure() {
|
||||
let command = Command::SendNativeTokenTransfer {
|
||||
from: ACC_SENDER.to_string(),
|
||||
|
||||
@ -3,14 +3,27 @@ use nssa_core::{
|
||||
program::{ProgramInput, read_nssa_inputs, write_nssa_outputs},
|
||||
};
|
||||
|
||||
/// [type (1) || amount (16) || name (6)]
|
||||
type Instruction = [u8; 23];
|
||||
// The token program has two functions:
|
||||
// 1. New token definition.
|
||||
// Arguments to this function are:
|
||||
// * Two **default** accounts: [definition_account, holding_account].
|
||||
// The first default account will be populated with the token definition account values. The second account will
|
||||
// be set to a token holding account for the new token, holding the entire total supply.
|
||||
// * An instruction data of 23-bytes, indicating the total supply and the token name, with
|
||||
// the following layout:
|
||||
// [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
|
||||
// The name cannot be equal to [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||
// 2. Token transfer
|
||||
// Arguments to this function are:
|
||||
// * Two accounts: [sender_account, recipient_account].
|
||||
// * An instruction data byte string of length 23, indicating the total supply and the token name, with the following layout
|
||||
// [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 || 0x00 || 0x00 || 0x00].
|
||||
|
||||
const TOKEN_DEFINITION_TYPE: u8 = 0;
|
||||
const TOKEN_DEFINITION_SIZE: usize = 23;
|
||||
const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
|
||||
|
||||
const TOKEN_HOLDING_TYPE: u8 = 1;
|
||||
const TOKEN_HOLDING_SIZE: usize = 49;
|
||||
const TOKEN_HOLDING_DATA_SIZE: usize = 49;
|
||||
|
||||
struct TokenDefinition {
|
||||
account_type: u8,
|
||||
@ -26,7 +39,7 @@ struct TokenHolding {
|
||||
|
||||
impl TokenDefinition {
|
||||
fn into_data(self) -> Vec<u8> {
|
||||
let mut bytes = [0; TOKEN_DEFINITION_SIZE];
|
||||
let mut bytes = [0; TOKEN_DEFINITION_DATA_SIZE];
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..7].copy_from_slice(&self.name);
|
||||
bytes[7..].copy_from_slice(&self.total_supply.to_le_bytes());
|
||||
@ -44,7 +57,7 @@ impl TokenHolding {
|
||||
}
|
||||
|
||||
fn parse(data: &[u8]) -> Option<Self> {
|
||||
if data.len() != TOKEN_HOLDING_SIZE && data[0] != TOKEN_HOLDING_TYPE {
|
||||
if data.len() != TOKEN_HOLDING_DATA_SIZE && data[0] != TOKEN_HOLDING_TYPE {
|
||||
None
|
||||
} else {
|
||||
let account_type = data[0];
|
||||
@ -59,7 +72,7 @@ impl TokenHolding {
|
||||
}
|
||||
|
||||
fn into_data(self) -> Data {
|
||||
let mut bytes = [0; TOKEN_HOLDING_SIZE];
|
||||
let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE];
|
||||
bytes[0] = self.account_type;
|
||||
bytes[1..33].copy_from_slice(&self.definition_id.to_bytes());
|
||||
bytes[33..].copy_from_slice(&self.balance.to_le_bytes());
|
||||
@ -147,6 +160,8 @@ fn new_definition(pre_states: Vec<AccountWithMetadata>, name: [u8; 6], total_sup
|
||||
);
|
||||
}
|
||||
|
||||
type Instruction = [u8; 23];
|
||||
|
||||
fn main() {
|
||||
let ProgramInput {
|
||||
pre_states,
|
||||
|
||||
@ -126,6 +126,63 @@ impl WalletCore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_new_token_definition(
|
||||
&self,
|
||||
definition_address: Address,
|
||||
supply_address: Address,
|
||||
name: [u8; 6],
|
||||
total_supply: u128,
|
||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||
let addresses = vec![definition_address, supply_address];
|
||||
let program_id = nssa::program::Program::token().id();
|
||||
// Instruction must be: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
|
||||
let mut instruction = [0; 23];
|
||||
instruction[1..17].copy_from_slice(&total_supply.to_le_bytes());
|
||||
instruction[17..].copy_from_slice(&name);
|
||||
let message =
|
||||
nssa::public_transaction::Message::try_new(program_id, addresses, vec![], instruction)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.sequencer_client.send_tx(tx).await?)
|
||||
}
|
||||
|
||||
pub async fn send_token_transfer(
|
||||
&self,
|
||||
sender_address: Address,
|
||||
recipient_address: Address,
|
||||
amount: u128,
|
||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||
let addresses = vec![sender_address, recipient_address];
|
||||
let program_id = nssa::program::Program::token().id();
|
||||
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 || 0x00 || 0x00 || 0x00].
|
||||
let mut instruction = [0; 23];
|
||||
instruction[0] = 0x01;
|
||||
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
|
||||
let Ok(nonces) = self.get_accounts_nonces(vec![sender_address]).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let message =
|
||||
nssa::public_transaction::Message::try_new(program_id, addresses, nonces, instruction)
|
||||
.unwrap();
|
||||
|
||||
let Some(signing_key) = self
|
||||
.storage
|
||||
.user_data
|
||||
.get_account_signing_key(&sender_address)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
let witness_set =
|
||||
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.sequencer_client.send_tx(tx).await?)
|
||||
}
|
||||
///Get account balance
|
||||
pub async fn get_account_balance(&self, acc: Address) -> Result<u128> {
|
||||
Ok(self
|
||||
@ -201,6 +258,24 @@ pub enum Command {
|
||||
#[arg(short, long)]
|
||||
addr: String,
|
||||
},
|
||||
NewTokenDefinition {
|
||||
#[arg(short, long)]
|
||||
definition_addr: String,
|
||||
#[arg(short, long)]
|
||||
supply_addr: String,
|
||||
#[arg(short, long)]
|
||||
name: String,
|
||||
#[arg(short, long)]
|
||||
total_supply: u128,
|
||||
},
|
||||
TokenTransfer {
|
||||
#[arg(short, long)]
|
||||
sender_addr: String,
|
||||
#[arg(short, long)]
|
||||
recipient_addr: String,
|
||||
#[arg(short, long)]
|
||||
balance_to_move: u128,
|
||||
},
|
||||
}
|
||||
|
||||
///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config
|
||||
@ -264,6 +339,41 @@ pub async fn execute_subcommand(command: Command) -> Result<()> {
|
||||
let account: HumanReadableAccount = wallet_core.get_account(addr).await?.into();
|
||||
println!("{}", serde_json::to_string(&account).unwrap());
|
||||
}
|
||||
Command::NewTokenDefinition {
|
||||
definition_addr,
|
||||
supply_addr,
|
||||
name,
|
||||
total_supply,
|
||||
} => {
|
||||
let name = name.as_bytes();
|
||||
if name.len() > 6 {
|
||||
// TODO: return error
|
||||
panic!();
|
||||
}
|
||||
let mut name_bytes = [0; 6];
|
||||
name_bytes[..name.len()].copy_from_slice(name);
|
||||
wallet_core
|
||||
.send_new_token_definition(
|
||||
definition_addr.parse().unwrap(),
|
||||
supply_addr.parse().unwrap(),
|
||||
name_bytes,
|
||||
total_supply,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Command::TokenTransfer {
|
||||
sender_addr,
|
||||
recipient_addr,
|
||||
balance_to_move,
|
||||
} => {
|
||||
wallet_core
|
||||
.send_token_transfer(
|
||||
sender_addr.parse().unwrap(),
|
||||
recipient_addr.parse().unwrap(),
|
||||
balance_to_move,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user