mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 23:03:06 +00:00
wip
This commit is contained in:
parent
e2494467ea
commit
a432019b23
@ -20,6 +20,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies.sequencer_core]
|
[dependencies.sequencer_core]
|
||||||
path = "../sequencer_core"
|
path = "../sequencer_core"
|
||||||
|
features = ["testnet"]
|
||||||
|
|
||||||
[dependencies.sequencer_runner]
|
[dependencies.sequencer_runner]
|
||||||
path = "../sequencer_runner"
|
path = "../sequencer_runner"
|
||||||
|
|||||||
@ -272,6 +272,50 @@ pub async fn test_success_two_transactions() {
|
|||||||
info!("Second TX Success!");
|
info!("Second TX Success!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn test_pinata() {
|
||||||
|
let pinata_addr = "cafe".repeat(16);
|
||||||
|
let pinata_prize = 150;
|
||||||
|
let solution = 989106;
|
||||||
|
let command = Command::ClaimPinata {
|
||||||
|
pinata_addr: pinata_addr.clone(),
|
||||||
|
winner_addr: ACC_SENDER.to_string(),
|
||||||
|
solution,
|
||||||
|
};
|
||||||
|
|
||||||
|
let wallet_config = fetch_config().unwrap();
|
||||||
|
|
||||||
|
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
|
||||||
|
|
||||||
|
let pinata_balance_pre = seq_client
|
||||||
|
.get_account_balance(pinata_addr.clone())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.balance;
|
||||||
|
|
||||||
|
wallet::execute_subcommand(command).await.unwrap();
|
||||||
|
|
||||||
|
info!("Waiting for next block creation");
|
||||||
|
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||||
|
|
||||||
|
info!("Checking correct balance move");
|
||||||
|
let pinata_balance_post = seq_client
|
||||||
|
.get_account_balance(pinata_addr.clone())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.balance;
|
||||||
|
|
||||||
|
let winner_balance_post = seq_client
|
||||||
|
.get_account_balance(ACC_SENDER.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.balance;
|
||||||
|
|
||||||
|
assert_eq!(pinata_balance_post, pinata_balance_pre - pinata_prize);
|
||||||
|
assert_eq!(winner_balance_post, 10000 + pinata_prize);
|
||||||
|
|
||||||
|
info!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! test_cleanup_wrap {
|
macro_rules! test_cleanup_wrap {
|
||||||
($home_dir:ident, $test_func:ident) => {{
|
($home_dir:ident, $test_func:ident) => {{
|
||||||
let res = pre_test($home_dir.clone()).await.unwrap();
|
let res = pre_test($home_dir.clone()).await.unwrap();
|
||||||
@ -307,11 +351,15 @@ pub async fn main_tests_runner() -> Result<()> {
|
|||||||
"test_success_two_transactions" => {
|
"test_success_two_transactions" => {
|
||||||
test_cleanup_wrap!(home_dir, test_success_two_transactions);
|
test_cleanup_wrap!(home_dir, test_success_two_transactions);
|
||||||
}
|
}
|
||||||
|
"test_pinata" => {
|
||||||
|
test_cleanup_wrap!(home_dir, test_pinata);
|
||||||
|
}
|
||||||
"all" => {
|
"all" => {
|
||||||
test_cleanup_wrap!(home_dir, test_success_move_to_another_account);
|
test_cleanup_wrap!(home_dir, test_success_move_to_another_account);
|
||||||
test_cleanup_wrap!(home_dir, test_success);
|
test_cleanup_wrap!(home_dir, test_success);
|
||||||
test_cleanup_wrap!(home_dir, test_failure);
|
test_cleanup_wrap!(home_dir, test_failure);
|
||||||
test_cleanup_wrap!(home_dir, test_success_two_transactions);
|
test_cleanup_wrap!(home_dir, test_success_two_transactions);
|
||||||
|
test_cleanup_wrap!(home_dir, test_pinata);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
anyhow::bail!("Unknown test name");
|
anyhow::bail!("Unknown test name");
|
||||||
|
|||||||
@ -18,3 +18,6 @@ hex = "0.4.3"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-program-methods = { path = "test_program_methods" }
|
test-program-methods = { path = "test_program_methods" }
|
||||||
hex-literal = "1.0.0"
|
hex-literal = "1.0.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use nssa_core::program::{read_nssa_inputs, write_nssa_outputs, ProgramInput};
|
use nssa_core::program::{ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||||
use risc0_zkvm::sha::{Impl, Sha256};
|
use risc0_zkvm::sha::{Impl, Sha256};
|
||||||
|
|
||||||
const PRIZE: u128 = 150;
|
const PRIZE: u128 = 150;
|
||||||
@ -21,10 +21,12 @@ impl Challenge {
|
|||||||
Self { difficulty, seed }
|
Self { difficulty, seed }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_nonce_valid(&self, nonce: Instruction) -> bool {
|
// Checks if the leftmost `self.difficulty` number of bytes of SHA256(self.data || solution) are
|
||||||
|
// zero.
|
||||||
|
fn validate_solution(&self, solution: Instruction) -> bool {
|
||||||
let mut bytes = [0; 32 + 16];
|
let mut bytes = [0; 32 + 16];
|
||||||
bytes.copy_from_slice(&self.seed);
|
bytes[..32].copy_from_slice(&self.seed);
|
||||||
bytes[32..].copy_from_slice(&nonce.to_le_bytes());
|
bytes[32..].copy_from_slice(&solution.to_le_bytes());
|
||||||
let digest: [u8; 32] = Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap();
|
let digest: [u8; 32] = Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap();
|
||||||
let difficulty = self.difficulty as usize;
|
let difficulty = self.difficulty as usize;
|
||||||
digest[..difficulty].iter().all(|&b| b == 0)
|
digest[..difficulty].iter().all(|&b| b == 0)
|
||||||
@ -33,7 +35,7 @@ impl Challenge {
|
|||||||
fn next_data(self) -> [u8; 33] {
|
fn next_data(self) -> [u8; 33] {
|
||||||
let mut result = [0; 33];
|
let mut result = [0; 33];
|
||||||
result[0] = self.difficulty;
|
result[0] = self.difficulty;
|
||||||
result.copy_from_slice(Impl::hash_bytes(&self.seed).as_bytes());
|
result[1..].copy_from_slice(Impl::hash_bytes(&self.seed).as_bytes());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,7 +46,7 @@ fn main() {
|
|||||||
// It is expected to receive only two accounts: [pinata_account, winner_account]
|
// It is expected to receive only two accounts: [pinata_account, winner_account]
|
||||||
let ProgramInput {
|
let ProgramInput {
|
||||||
pre_states,
|
pre_states,
|
||||||
instruction: nonce,
|
instruction: solution,
|
||||||
} = read_nssa_inputs::<Instruction>();
|
} = read_nssa_inputs::<Instruction>();
|
||||||
|
|
||||||
let [pinata, winner] = match pre_states.try_into() {
|
let [pinata, winner] = match pre_states.try_into() {
|
||||||
@ -54,7 +56,7 @@ fn main() {
|
|||||||
|
|
||||||
let data = Challenge::new(&pinata.account.data);
|
let data = Challenge::new(&pinata.account.data);
|
||||||
|
|
||||||
if !data.is_nonce_valid(nonce) {
|
if !data.validate_solution(solution) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,9 @@ use nssa_core::{
|
|||||||
account::{Account, AccountWithMetadata},
|
account::{Account, AccountWithMetadata},
|
||||||
program::{InstructionData, ProgramId, ProgramOutput},
|
program::{InstructionData, ProgramId, ProgramOutput},
|
||||||
};
|
};
|
||||||
use program_methods::{AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, PINATA_ELF, PINATA_ID};
|
use program_methods::{
|
||||||
|
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, PINATA_ELF, PINATA_ID,
|
||||||
|
};
|
||||||
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec};
|
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@ -73,11 +75,14 @@ impl Program {
|
|||||||
elf: AUTHENTICATED_TRANSFER_ELF,
|
elf: AUTHENTICATED_TRANSFER_ELF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This is for testnet only, consider refactoring to have this not compiled for mainnet
|
||||||
|
impl Program {
|
||||||
pub fn pinata() -> Self {
|
pub fn pinata() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: PINATA_ID,
|
id: PINATA_ID,
|
||||||
elf: PINATA_ELF
|
elf: PINATA_ELF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,41 +86,6 @@ impl V01State {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_pinata_accounts(&mut self) {
|
|
||||||
self.insert_program(Program::pinata());
|
|
||||||
|
|
||||||
let mut rng = OsRng;
|
|
||||||
let mut seed = [0; 32];
|
|
||||||
|
|
||||||
rng.fill_bytes(&mut seed);
|
|
||||||
self.public_state.insert(
|
|
||||||
"6a79aee868a1c641ea895582af7ddd6f2da339e3091a67eddcbfdaa1b9010001"
|
|
||||||
.parse()
|
|
||||||
.unwrap(),
|
|
||||||
Account {
|
|
||||||
program_owner: Program::pinata().id(),
|
|
||||||
balance: 1500,
|
|
||||||
// Difficulty: 3
|
|
||||||
data: std::iter::once(3).chain(seed).collect(),
|
|
||||||
nonce: 0,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
rng.fill_bytes(&mut seed);
|
|
||||||
self.public_state.insert(
|
|
||||||
"6a79aee868a1c641ea895582af7ddd6f2da339e3091a67eddcbfdaa1b9010002"
|
|
||||||
.parse()
|
|
||||||
.unwrap(),
|
|
||||||
Account {
|
|
||||||
program_owner: Program::pinata().id(),
|
|
||||||
balance: 1500,
|
|
||||||
// Difficulty: 4
|
|
||||||
data: std::iter::once(4).chain(seed).collect(),
|
|
||||||
nonce: 0,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn insert_program(&mut self, program: Program) {
|
pub(crate) fn insert_program(&mut self, program: Program) {
|
||||||
self.builtin_programs.insert(program.id(), program);
|
self.builtin_programs.insert(program.id(), program);
|
||||||
}
|
}
|
||||||
@ -242,6 +207,24 @@ impl V01State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This is for testnet only, consider refactoring to have this not compiled for mainnet
|
||||||
|
impl V01State {
|
||||||
|
pub fn add_pinata_program(&mut self, address: Address) {
|
||||||
|
self.insert_program(Program::pinata());
|
||||||
|
|
||||||
|
self.public_state.insert(
|
||||||
|
address,
|
||||||
|
Account {
|
||||||
|
program_owner: Program::pinata().id(),
|
||||||
|
balance: 1500,
|
||||||
|
// Difficulty: 3
|
||||||
|
data: vec![3; 33],
|
||||||
|
nonce: 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
|
|
||||||
|
|||||||
@ -22,3 +22,7 @@ path = "../common"
|
|||||||
|
|
||||||
[dependencies.nssa]
|
[dependencies.nssa]
|
||||||
path = "../nssa"
|
path = "../nssa"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
testnet = []
|
||||||
|
|||||||
@ -26,9 +26,13 @@ impl SequecerChainStore {
|
|||||||
.map(|acc_data| (acc_data.addr.parse().unwrap(), acc_data.balance))
|
.map(|acc_data| (acc_data.addr.parse().unwrap(), acc_data.balance))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "testnet"))]
|
||||||
|
let state = nssa::V01State::new_with_genesis_accounts(&init_accs);
|
||||||
|
|
||||||
|
#[cfg(feature = "testnet")]
|
||||||
let state = {
|
let state = {
|
||||||
let mut this = nssa::V01State::new_with_genesis_accounts(&init_accs);
|
let mut this = nssa::V01State::new_with_genesis_accounts(&init_accs);
|
||||||
this.add_pinata_accounts();
|
this.add_pinata_program("cafe".repeat(16).parse().unwrap());
|
||||||
this
|
this
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -77,9 +77,7 @@ pub async fn main_runner() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ToDo: Add restart on failures
|
//ToDo: Add restart on failures
|
||||||
let (_, main_loop_handle) = startup_sequencer(app_config).await?;
|
let (_, _) = startup_sequencer(app_config).await?;
|
||||||
|
|
||||||
main_loop_handle.await??;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,6 +84,24 @@ impl WalletCore {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn claim_pinata(
|
||||||
|
&self,
|
||||||
|
pinata_addr: Address,
|
||||||
|
winner_addr: Address,
|
||||||
|
solution: u128,
|
||||||
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
|
let addresses = vec![pinata_addr, winner_addr];
|
||||||
|
let program_id = nssa::program::Program::pinata().id();
|
||||||
|
let message =
|
||||||
|
nssa::public_transaction::Message::try_new(program_id, addresses, vec![], solution)
|
||||||
|
.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_public_native_token_transfer(
|
pub async fn send_public_native_token_transfer(
|
||||||
&self,
|
&self,
|
||||||
from: Address,
|
from: Address,
|
||||||
@ -191,6 +209,20 @@ pub enum Command {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
addr: String,
|
addr: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO: This is for testnet only, consider refactoring to have this not compiled for mainnet
|
||||||
|
// Claim piñata prize
|
||||||
|
ClaimPinata {
|
||||||
|
///pinata_addr - valid 32 byte hex string
|
||||||
|
#[arg(long)]
|
||||||
|
pinata_addr: String,
|
||||||
|
///winner_addr - valid 32 byte hex string
|
||||||
|
#[arg(long)]
|
||||||
|
winner_addr: String,
|
||||||
|
///solution - solution to pinata challenge
|
||||||
|
#[arg(long)]
|
||||||
|
solution: u128,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config
|
///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config
|
||||||
@ -228,7 +260,7 @@ pub async fn execute_subcommand(command: Command) -> Result<()> {
|
|||||||
|
|
||||||
let key = wallet_core.storage.user_data.get_account_signing_key(&addr);
|
let key = wallet_core.storage.user_data.get_account_signing_key(&addr);
|
||||||
|
|
||||||
info!("Generated new account with addr {addr:#?}");
|
println!("Generated new account with addr {addr}");
|
||||||
info!("With key {key:#?}");
|
info!("With key {key:#?}");
|
||||||
}
|
}
|
||||||
Command::FetchTx { tx_hash } => {
|
Command::FetchTx { tx_hash } => {
|
||||||
@ -243,13 +275,27 @@ pub async fn execute_subcommand(command: Command) -> Result<()> {
|
|||||||
let addr = Address::from_str(&addr)?;
|
let addr = Address::from_str(&addr)?;
|
||||||
|
|
||||||
let balance = wallet_core.get_account_balance(addr).await?;
|
let balance = wallet_core.get_account_balance(addr).await?;
|
||||||
info!("Accounts {addr:#?} balance is {balance}");
|
println!("Accounts {addr} balance is {balance}");
|
||||||
}
|
}
|
||||||
Command::GetAccountNonce { addr } => {
|
Command::GetAccountNonce { addr } => {
|
||||||
let addr = Address::from_str(&addr)?;
|
let addr = Address::from_str(&addr)?;
|
||||||
|
|
||||||
let nonce = wallet_core.get_accounts_nonces(vec![addr]).await?[0];
|
let nonce = wallet_core.get_accounts_nonces(vec![addr]).await?[0];
|
||||||
info!("Accounts {addr:#?} nonce is {nonce}");
|
println!("Accounts {addr} nonce is {nonce}");
|
||||||
|
}
|
||||||
|
Command::ClaimPinata {
|
||||||
|
pinata_addr,
|
||||||
|
winner_addr,
|
||||||
|
solution,
|
||||||
|
} => {
|
||||||
|
let res = wallet_core
|
||||||
|
.claim_pinata(
|
||||||
|
pinata_addr.parse().unwrap(),
|
||||||
|
winner_addr.parse().unwrap(),
|
||||||
|
solution,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
info!("Results of tx send is {res:#?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user