mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-05 23:03:06 +00:00
Merge branch 'Pravdyvy/state-transition-token-transfer' into schouhy/prevent-replay-attacks-with-nonces
This commit is contained in:
commit
484c22b649
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1141,6 +1141,12 @@ version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
@ -4372,12 +4378,14 @@ dependencies = [
|
||||
"serde_json",
|
||||
"storage",
|
||||
"tempfile",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequencer_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"accounts",
|
||||
"actix",
|
||||
"actix-cors",
|
||||
"actix-web",
|
||||
@ -4859,6 +4867,15 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.1"
|
||||
|
||||
@ -45,6 +45,7 @@ tempfile = "3.14.0"
|
||||
light-poseidon = "0.3.0"
|
||||
ark-bn254 = "0.5.0"
|
||||
ark-ff = "0.5.0"
|
||||
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
|
||||
|
||||
rocksdb = { version = "0.21.0", default-features = false, features = [
|
||||
"snappy",
|
||||
|
||||
10
common/src/execution_input.rs
Normal file
10
common/src/execution_input.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::merkle_tree_public::TreeHashType;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PublicNativeTokenSend {
|
||||
pub from: TreeHashType,
|
||||
pub to: TreeHashType,
|
||||
pub balance_to_move: u64,
|
||||
}
|
||||
@ -3,6 +3,7 @@ use serde::Deserialize;
|
||||
|
||||
pub mod block;
|
||||
pub mod commitment;
|
||||
pub mod execution_input;
|
||||
pub mod merkle_tree_public;
|
||||
pub mod nullifier;
|
||||
pub mod rpc_primitives;
|
||||
|
||||
@ -34,6 +34,9 @@ pub struct GetGenesisIdRequest {}
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GetLastBlockRequest {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GetInitialTestnetAccountsRequest {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GetAccountBalanceRequest {
|
||||
pub address: String,
|
||||
@ -50,6 +53,7 @@ parse_request!(SendTxRequest);
|
||||
parse_request!(GetBlockDataRequest);
|
||||
parse_request!(GetGenesisIdRequest);
|
||||
parse_request!(GetLastBlockRequest);
|
||||
parse_request!(GetInitialTestnetAccountsRequest);
|
||||
parse_request!(GetAccountBalanceRequest);
|
||||
parse_request!(GetTransactionByHashRequest);
|
||||
|
||||
|
||||
@ -235,8 +235,8 @@ pub type SignaturePrivateKey = SigningKey;
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||
pub struct Transaction {
|
||||
body: TransactionBody,
|
||||
signature: TransactionSignature,
|
||||
public_key: VerifyingKey,
|
||||
pub signature: TransactionSignature,
|
||||
pub public_key: VerifyingKey,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
|
||||
@ -5,6 +5,7 @@ use anyhow::Result;
|
||||
use block_store::NodeBlockStore;
|
||||
use common::{
|
||||
block::Block,
|
||||
execution_input::PublicNativeTokenSend,
|
||||
merkle_tree_public::merkle_tree::{PublicTransactionMerkleTree, UTXOCommitmentsMerkleTree},
|
||||
nullifier::UTXONullifier,
|
||||
utxo_commitment::UTXOCommitment,
|
||||
@ -158,6 +159,20 @@ impl NodeChainStore {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
let native_transfer =
|
||||
serde_json::from_slice::<PublicNativeTokenSend>(&tx.body().execution_input);
|
||||
|
||||
if let Ok(transfer) = native_transfer {
|
||||
if let Some(acc_sender) = self.acc_map.get_mut(&transfer.from) {
|
||||
//Can panic, we depend on sequencer maintaining chain consistency here
|
||||
acc_sender.balance -= transfer.balance_to_move;
|
||||
|
||||
if let Some(acc_rec) = self.acc_map.get_mut(&transfer.to) {
|
||||
acc_rec.balance += transfer.balance_to_move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,9 @@ use std::sync::{
|
||||
Arc,
|
||||
};
|
||||
|
||||
use common::{transaction::Transaction, ExecutionFailureKind};
|
||||
use common::{
|
||||
execution_input::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind,
|
||||
};
|
||||
|
||||
use accounts::{
|
||||
account_core::{Account, AccountAddress},
|
||||
@ -101,7 +103,14 @@ impl NodeCore {
|
||||
|
||||
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block;
|
||||
|
||||
let initial_accounts_ser = client.get_initial_testnet_accounts().await?;
|
||||
let initial_accounts: Vec<Account> =
|
||||
initial_accounts_ser.into_iter().map(Into::into).collect();
|
||||
|
||||
let (mut storage, mut chain_height) = NodeChainStore::new(config.clone(), genesis_block)?;
|
||||
for acc in initial_accounts {
|
||||
storage.acc_map.insert(acc.address, acc);
|
||||
}
|
||||
|
||||
pre_start::setup_empty_sc_states(&storage).await?;
|
||||
|
||||
@ -942,6 +951,70 @@ impl NodeCore {
|
||||
// Ok(self.sequencer_client.send_tx(tx, tx_roots).await?)
|
||||
// }
|
||||
|
||||
// ToDo: Currently untested due to need for end-to-end integration tests.
|
||||
// Add integration tests to cover this functionality
|
||||
pub async fn send_public_native_token_transfer(
|
||||
&self,
|
||||
from: AccountAddress,
|
||||
to: AccountAddress,
|
||||
balance_to_move: u64,
|
||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||
let tx_roots = self.get_roots().await;
|
||||
|
||||
let public_context = {
|
||||
let read_guard = self.storage.read().await;
|
||||
|
||||
read_guard.produce_context(from)
|
||||
};
|
||||
|
||||
let (tweak, secret_r, commitment) = pedersen_commitment_vec(
|
||||
//Will not panic, as public context is serializable
|
||||
public_context.produce_u64_list_from_context().unwrap(),
|
||||
);
|
||||
|
||||
let sc_addr = hex::encode([0; 32]);
|
||||
|
||||
//Native contract does not change its state
|
||||
let state_changes: Vec<DataBlobChangeVariant> = vec![];
|
||||
let new_len = 0;
|
||||
let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len);
|
||||
|
||||
let tx: TransactionBody =
|
||||
sc_core::transaction_payloads_tools::create_public_transaction_payload(
|
||||
serde_json::to_vec(&PublicNativeTokenSend {
|
||||
from,
|
||||
to,
|
||||
balance_to_move,
|
||||
})
|
||||
.unwrap(),
|
||||
commitment,
|
||||
tweak,
|
||||
secret_r,
|
||||
sc_addr,
|
||||
state_changes,
|
||||
);
|
||||
tx.log();
|
||||
|
||||
{
|
||||
let read_guard = self.storage.read().await;
|
||||
|
||||
let account = read_guard.acc_map.get(&from);
|
||||
|
||||
if let Some(account) = account {
|
||||
let key_to_sign_transaction = account.key_holder.get_pub_account_signing_key();
|
||||
|
||||
let signed_transaction = Transaction::new(tx, key_to_sign_transaction);
|
||||
|
||||
Ok(self
|
||||
.sequencer_client
|
||||
.send_tx(signed_transaction, tx_roots)
|
||||
.await?)
|
||||
} else {
|
||||
Err(ExecutionFailureKind::AmountMismatchError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_private_send_tx(
|
||||
&self,
|
||||
utxo: UTXO,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
use accounts::account_core::Account;
|
||||
use accounts::account_core::{Account, AccountForSerialization};
|
||||
use anyhow::Result;
|
||||
use common::rpc_primitives::requests::{
|
||||
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
|
||||
RegisterAccountRequest, RegisterAccountResponse,
|
||||
GetInitialTestnetAccountsRequest, RegisterAccountRequest, RegisterAccountResponse,
|
||||
};
|
||||
use common::transaction::Transaction;
|
||||
use common::{SequencerClientError, SequencerRpcError};
|
||||
@ -121,4 +121,21 @@ impl SequencerClient {
|
||||
|
||||
Ok(resp_deser)
|
||||
}
|
||||
|
||||
pub async fn get_initial_testnet_accounts(
|
||||
&self,
|
||||
) -> Result<Vec<AccountForSerialization>, SequencerClientError> {
|
||||
let acc_req = GetInitialTestnetAccountsRequest {};
|
||||
|
||||
let req = serde_json::to_value(acc_req).unwrap();
|
||||
|
||||
let resp = self
|
||||
.call_method_with_payload("get_initial_testnet_accounts", req)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let resp_deser = serde_json::from_value(resp).unwrap();
|
||||
|
||||
Ok(resp_deser)
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ serde.workspace = true
|
||||
rand.workspace = true
|
||||
elliptic-curve.workspace = true
|
||||
k256.workspace = true
|
||||
tiny-keccak.workspace = true
|
||||
tempfile.workspace = true
|
||||
|
||||
[dependencies.storage]
|
||||
|
||||
@ -1,17 +1,8 @@
|
||||
use accounts::account_core::AccountForSerialization;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
//
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
///Helperstruct for account serialization
|
||||
pub struct AccountInitialData {
|
||||
///Hex encoded `AccountAddress`
|
||||
pub addr: String,
|
||||
pub balance: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct SequencerConfig {
|
||||
///Home dir of sequencer storage
|
||||
pub home: PathBuf,
|
||||
@ -27,6 +18,6 @@ pub struct SequencerConfig {
|
||||
pub block_create_timeout_millis: u64,
|
||||
///Port to listen
|
||||
pub port: u16,
|
||||
///List of pairs (account_address, initial_balance)
|
||||
pub initial_accounts: Vec<AccountInitialData>,
|
||||
///List of initial accounts data
|
||||
pub initial_accounts: Vec<AccountForSerialization>,
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use accounts::account_core::AccountAddress;
|
||||
use anyhow::Result;
|
||||
use common::{
|
||||
block::{Block, HashableBlockData},
|
||||
execution_input::PublicNativeTokenSend,
|
||||
merkle_tree_public::TreeHashType,
|
||||
nullifier::UTXONullifier,
|
||||
transaction::{AuthenticatedTransaction, Transaction, TransactionBody, TxKind},
|
||||
@ -14,6 +15,7 @@ use mempool::MemPool;
|
||||
use mempool_transaction::MempoolTransaction;
|
||||
use sequencer_store::SequecerChainStore;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
|
||||
pub mod config;
|
||||
pub mod mempool_transaction;
|
||||
@ -37,6 +39,9 @@ pub enum TransactionMalformationErrorKind {
|
||||
ChainStateFurtherThanTransactionState { tx: TreeHashType },
|
||||
FailedToInsert { tx: TreeHashType, details: String },
|
||||
InvalidSignature,
|
||||
IncorrectSender,
|
||||
BalanceMismatch { tx: TreeHashType },
|
||||
FailedToDecode { tx: TreeHashType },
|
||||
}
|
||||
|
||||
impl Display for TransactionMalformationErrorKind {
|
||||
@ -137,6 +142,20 @@ impl SequencerCore {
|
||||
_ => {}
|
||||
};
|
||||
|
||||
//Correct sender check
|
||||
if let Ok(native_transfer_action) =
|
||||
serde_json::from_slice::<PublicNativeTokenSend>(execution_input)
|
||||
{
|
||||
let mut output = [0; 32];
|
||||
let mut keccak_hasher = Keccak::v256();
|
||||
keccak_hasher.update(&tx.transaction().public_key.to_sec1_bytes());
|
||||
keccak_hasher.finalize(&mut output);
|
||||
|
||||
if native_transfer_action.from != output {
|
||||
return Err(TransactionMalformationErrorKind::IncorrectSender);
|
||||
}
|
||||
}
|
||||
|
||||
//Tree checks
|
||||
let tx_tree_check = self.store.pub_tx_store.get_tx(tx_hash).is_some();
|
||||
let nullifier_tree_check = nullifier_created_hashes.iter().any(|nullifier_hash| {
|
||||
@ -203,9 +222,39 @@ impl SequencerCore {
|
||||
let TransactionBody {
|
||||
ref utxo_commitments_created_hashes,
|
||||
ref nullifier_created_hashes,
|
||||
execution_input,
|
||||
..
|
||||
} = mempool_tx.auth_tx.transaction().body();
|
||||
|
||||
let tx_hash = *mempool_tx.auth_tx.hash();
|
||||
|
||||
//Balance check
|
||||
if let Ok(native_transfer_action) =
|
||||
serde_json::from_slice::<PublicNativeTokenSend>(execution_input)
|
||||
{
|
||||
let from_balance = self
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&native_transfer_action.from);
|
||||
let to_balance = self
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&native_transfer_action.to);
|
||||
|
||||
if from_balance >= native_transfer_action.balance_to_move {
|
||||
self.store.acc_store.set_account_balance(
|
||||
&native_transfer_action.from,
|
||||
from_balance - native_transfer_action.balance_to_move,
|
||||
);
|
||||
self.store.acc_store.set_account_balance(
|
||||
&native_transfer_action.to,
|
||||
to_balance + native_transfer_action.balance_to_move,
|
||||
);
|
||||
} else {
|
||||
return Err(TransactionMalformationErrorKind::BalanceMismatch { tx: tx_hash });
|
||||
}
|
||||
}
|
||||
|
||||
for utxo_comm in utxo_commitments_created_hashes {
|
||||
self.store
|
||||
.utxo_commitments_store
|
||||
@ -270,18 +319,17 @@ impl SequencerCore {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{config::AccountInitialData, sequencer_store::accounts_store};
|
||||
|
||||
use super::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use accounts::account_core::AccountForSerialization;
|
||||
use common::transaction::{SignaturePrivateKey, Transaction, TransactionBody, TxKind};
|
||||
use mempool_transaction::MempoolTransaction;
|
||||
use rand::Rng;
|
||||
use secp256k1_zkp::Tweak;
|
||||
|
||||
fn setup_sequencer_config_variable_initial_accounts(
|
||||
initial_accounts: Vec<AccountInitialData>,
|
||||
initial_accounts: Vec<AccountForSerialization>,
|
||||
) -> SequencerConfig {
|
||||
let mut rng = rand::thread_rng();
|
||||
let random_u8: u8 = rng.gen();
|
||||
@ -301,18 +349,243 @@ mod tests {
|
||||
}
|
||||
|
||||
fn setup_sequencer_config() -> SequencerConfig {
|
||||
let initial_accounts = vec![
|
||||
AccountInitialData {
|
||||
addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c"
|
||||
.to_string(),
|
||||
balance: 10,
|
||||
let initial_acc1 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"balance": 10,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718",
|
||||
"pub_account_signing_key": [
|
||||
244,
|
||||
88,
|
||||
134,
|
||||
61,
|
||||
35,
|
||||
209,
|
||||
229,
|
||||
101,
|
||||
85,
|
||||
35,
|
||||
140,
|
||||
140,
|
||||
192,
|
||||
226,
|
||||
83,
|
||||
83,
|
||||
190,
|
||||
189,
|
||||
110,
|
||||
8,
|
||||
89,
|
||||
127,
|
||||
147,
|
||||
142,
|
||||
157,
|
||||
204,
|
||||
51,
|
||||
109,
|
||||
189,
|
||||
92,
|
||||
144,
|
||||
68
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4"
|
||||
},
|
||||
AccountInitialData {
|
||||
addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31"
|
||||
.to_string(),
|
||||
balance: 100,
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506",
|
||||
"viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF"
|
||||
},
|
||||
];
|
||||
"viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_acc2 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"balance": 100,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271",
|
||||
"pub_account_signing_key": [
|
||||
136,
|
||||
105,
|
||||
9,
|
||||
53,
|
||||
180,
|
||||
145,
|
||||
64,
|
||||
5,
|
||||
235,
|
||||
174,
|
||||
62,
|
||||
211,
|
||||
206,
|
||||
116,
|
||||
185,
|
||||
24,
|
||||
214,
|
||||
62,
|
||||
244,
|
||||
64,
|
||||
224,
|
||||
59,
|
||||
120,
|
||||
150,
|
||||
30,
|
||||
249,
|
||||
160,
|
||||
46,
|
||||
189,
|
||||
254,
|
||||
47,
|
||||
244
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179"
|
||||
},
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122",
|
||||
"viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7"
|
||||
},
|
||||
"viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_accounts = vec![initial_acc1, initial_acc2];
|
||||
|
||||
setup_sequencer_config_variable_initial_accounts(initial_accounts)
|
||||
}
|
||||
@ -364,68 +637,269 @@ mod tests {
|
||||
assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10);
|
||||
assert_eq!(sequencer.sequencer_config.port, 8080);
|
||||
|
||||
let acc1_addr: [u8; 32] =
|
||||
hex::decode("bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let acc2_addr: [u8; 32] =
|
||||
hex::decode("20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let acc1_addr = config.initial_accounts[0].address;
|
||||
let acc2_addr = config.initial_accounts[1].address;
|
||||
|
||||
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
||||
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
||||
|
||||
assert_eq!(
|
||||
10,
|
||||
sequencer
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&acc1_addr)
|
||||
.unwrap()
|
||||
sequencer.store.acc_store.get_account_balance(&acc1_addr)
|
||||
);
|
||||
assert_eq!(
|
||||
100,
|
||||
sequencer
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&acc2_addr)
|
||||
.unwrap()
|
||||
sequencer.store.acc_store.get_account_balance(&acc2_addr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_start_different_intial_accounts() {
|
||||
let initial_accounts = vec![
|
||||
AccountInitialData {
|
||||
addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff"
|
||||
.to_string(),
|
||||
balance: 1000,
|
||||
fn test_start_different_intial_accounts_balances() {
|
||||
let initial_acc1 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"balance": 1000,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718",
|
||||
"pub_account_signing_key": [
|
||||
244,
|
||||
88,
|
||||
134,
|
||||
61,
|
||||
35,
|
||||
209,
|
||||
229,
|
||||
101,
|
||||
85,
|
||||
35,
|
||||
140,
|
||||
140,
|
||||
192,
|
||||
226,
|
||||
83,
|
||||
83,
|
||||
190,
|
||||
189,
|
||||
110,
|
||||
8,
|
||||
89,
|
||||
127,
|
||||
147,
|
||||
142,
|
||||
157,
|
||||
204,
|
||||
51,
|
||||
109,
|
||||
189,
|
||||
92,
|
||||
144,
|
||||
68
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4"
|
||||
},
|
||||
AccountInitialData {
|
||||
addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff"
|
||||
.to_string(),
|
||||
balance: 1000,
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506",
|
||||
"viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF"
|
||||
},
|
||||
];
|
||||
"viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_acc2 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"balance": 1000,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271",
|
||||
"pub_account_signing_key": [
|
||||
136,
|
||||
105,
|
||||
9,
|
||||
53,
|
||||
180,
|
||||
145,
|
||||
64,
|
||||
5,
|
||||
235,
|
||||
174,
|
||||
62,
|
||||
211,
|
||||
206,
|
||||
116,
|
||||
185,
|
||||
24,
|
||||
214,
|
||||
62,
|
||||
244,
|
||||
64,
|
||||
224,
|
||||
59,
|
||||
120,
|
||||
150,
|
||||
30,
|
||||
249,
|
||||
160,
|
||||
46,
|
||||
189,
|
||||
254,
|
||||
47,
|
||||
244
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179"
|
||||
},
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122",
|
||||
"viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7"
|
||||
},
|
||||
"viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_accounts = vec![initial_acc1, initial_acc2];
|
||||
|
||||
let intial_accounts_len = initial_accounts.len();
|
||||
|
||||
let config = setup_sequencer_config_variable_initial_accounts(initial_accounts);
|
||||
let sequencer = SequencerCore::start_from_config(config.clone());
|
||||
|
||||
let acc1_addr: [u8; 32] =
|
||||
hex::decode("bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let acc2_addr: [u8; 32] =
|
||||
hex::decode("20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let acc1_addr = config.initial_accounts[0].address;
|
||||
let acc2_addr = config.initial_accounts[1].address;
|
||||
|
||||
assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
|
||||
assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
|
||||
@ -434,19 +908,11 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
1000,
|
||||
sequencer
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&acc1_addr)
|
||||
.unwrap()
|
||||
sequencer.store.acc_store.get_account_balance(&acc1_addr)
|
||||
);
|
||||
assert_eq!(
|
||||
1000,
|
||||
sequencer
|
||||
.store
|
||||
.acc_store
|
||||
.get_account_balance(&acc2_addr)
|
||||
.unwrap()
|
||||
sequencer.store.acc_store.get_account_balance(&acc2_addr)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -66,9 +66,29 @@ impl SequencerAccountsStore {
|
||||
|
||||
///Check `account_addr` balance,
|
||||
///
|
||||
///returns `None`, if account address not found
|
||||
pub fn get_account_balance(&self, account_addr: &AccountAddress) -> Option<u64> {
|
||||
self.accounts.get(account_addr).map(|acc| acc.balance)
|
||||
///returns 0, if account address not found
|
||||
pub fn get_account_balance(&self, account_addr: &AccountAddress) -> u64 {
|
||||
self.accounts
|
||||
.get(account_addr)
|
||||
.map(|acc| acc.balance)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
///Update `account_addr` balance,
|
||||
///
|
||||
/// returns 0, if account address not found, otherwise returns previous balance
|
||||
pub fn set_account_balance(&mut self, account_addr: &AccountAddress, new_balance: u64) -> u64 {
|
||||
let acc_data = self.accounts.get_mut(account_addr);
|
||||
|
||||
acc_data
|
||||
.map(|data| {
|
||||
let old_balance = data.balance;
|
||||
|
||||
data.balance = new_balance;
|
||||
|
||||
old_balance
|
||||
})
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
///Remove account from storage
|
||||
@ -80,15 +100,11 @@ impl SequencerAccountsStore {
|
||||
&mut self,
|
||||
account_addr: AccountAddress,
|
||||
) -> Result<Option<AccountAddress>> {
|
||||
if let Some(account_balance) = self.get_account_balance(&account_addr) {
|
||||
if account_balance == 0 {
|
||||
if self.get_account_balance(&account_addr) == 0 {
|
||||
Ok(self.accounts.remove(&account_addr).map(|data| data.address))
|
||||
} else {
|
||||
anyhow::bail!("Chain consistency violation: It is forbidden to remove account with nonzero balance");
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
///Number of accounts present in store
|
||||
@ -157,7 +173,7 @@ mod tests {
|
||||
|
||||
assert!(seq_acc_store.contains_account(&[1; 32]));
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[1; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[1; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 0);
|
||||
}
|
||||
@ -202,11 +218,11 @@ mod tests {
|
||||
assert!(seq_acc_store.contains_account(&[1; 32]));
|
||||
assert!(seq_acc_store.contains_account(&[2; 32]));
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[1; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[1; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 12);
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[2; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[2; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 100);
|
||||
}
|
||||
@ -220,15 +236,15 @@ mod tests {
|
||||
assert!(seq_acc_store.contains_account(&[7; 32]));
|
||||
assert!(seq_acc_store.contains_account(&[8; 32]));
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[6; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[6; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 120);
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[7; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[7; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 15);
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[8; 32]).unwrap();
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[8; 32]);
|
||||
|
||||
assert_eq!(acc_balance, 10);
|
||||
}
|
||||
@ -240,7 +256,7 @@ mod tests {
|
||||
|
||||
let acc_balance = seq_acc_store.get_account_balance(&[9; 32]);
|
||||
|
||||
assert!(acc_balance.is_none());
|
||||
assert_eq!(acc_balance, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use std::{collections::HashSet, path::Path};
|
||||
|
||||
use accounts::account_core::AccountForSerialization;
|
||||
use accounts_store::SequencerAccountsStore;
|
||||
use block_store::SequecerBlockStore;
|
||||
use common::{
|
||||
@ -9,8 +10,6 @@ use common::{
|
||||
};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
|
||||
use crate::config::AccountInitialData;
|
||||
|
||||
pub mod accounts_store;
|
||||
pub mod block_store;
|
||||
|
||||
@ -27,24 +26,14 @@ impl SequecerChainStore {
|
||||
home_dir: &Path,
|
||||
genesis_id: u64,
|
||||
is_genesis_random: bool,
|
||||
initial_accounts: &[AccountInitialData],
|
||||
initial_accounts: &[AccountForSerialization],
|
||||
) -> Self {
|
||||
let acc_data_decoded: Vec<([u8; 32], u64)> = initial_accounts
|
||||
let accs_pregenerated: Vec<_> = initial_accounts
|
||||
.iter()
|
||||
.map(|acc_data| {
|
||||
(
|
||||
//ToDo: Handle this error for direct error message
|
||||
//Failure to produce account address is critical, so error handling is needed only for clarity
|
||||
hex::decode(acc_data.addr.clone())
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
acc_data.balance,
|
||||
)
|
||||
})
|
||||
.map(|acc| (acc.address, acc.balance))
|
||||
.collect();
|
||||
|
||||
let acc_store = SequencerAccountsStore::new(&acc_data_decoded);
|
||||
let acc_store = SequencerAccountsStore::new(&accs_pregenerated);
|
||||
let nullifier_store = HashSet::new();
|
||||
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
|
||||
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
|
||||
|
||||
@ -21,6 +21,9 @@ tokio.workspace = true
|
||||
[dependencies.mempool]
|
||||
path = "../mempool"
|
||||
|
||||
[dependencies.accounts]
|
||||
path = "../accounts"
|
||||
|
||||
[dependencies.consensus]
|
||||
path = "../consensus"
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use accounts::account_core::AccountForSerialization;
|
||||
use actix_web::Error as HttpError;
|
||||
use serde_json::Value;
|
||||
|
||||
@ -8,8 +9,8 @@ use common::{
|
||||
message::{Message, Request},
|
||||
parser::RpcRequest,
|
||||
requests::{
|
||||
GetAccountBalanceRequest, GetAccountBalanceResponse, GetTransactionByHashRequest,
|
||||
GetTransactionByHashResponse,
|
||||
GetAccountBalanceRequest, GetAccountBalanceResponse, GetInitialTestnetAccountsRequest,
|
||||
GetTransactionByHashRequest, GetTransactionByHashResponse,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -35,6 +36,8 @@ pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER";
|
||||
|
||||
pub const SUCCESS: &str = "Success";
|
||||
|
||||
pub const GET_INITIAL_TESTNET_ACCOUNTS: &str = "get_initial_testnet_accounts";
|
||||
|
||||
impl JsonHandler {
|
||||
pub async fn process(&self, message: Message) -> Result<Message, HttpError> {
|
||||
let id = message.id();
|
||||
@ -140,6 +143,21 @@ impl JsonHandler {
|
||||
respond(helperstruct)
|
||||
}
|
||||
|
||||
/// Returns the initial accounts for testnet
|
||||
/// ToDo: Useful only for testnet and needs to be removed later
|
||||
async fn get_initial_testnet_accounts(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
let _get_initial_testnet_accounts_request =
|
||||
GetInitialTestnetAccountsRequest::parse(Some(request.params))?;
|
||||
|
||||
let accounts_for_serialization: Vec<AccountForSerialization> = {
|
||||
let state = self.sequencer_state.lock().await;
|
||||
|
||||
state.sequencer_config.initial_accounts.clone()
|
||||
};
|
||||
|
||||
respond(accounts_for_serialization)
|
||||
}
|
||||
|
||||
/// Returns the balance of the account at the given address.
|
||||
/// The address must be a valid hex string of the correct length.
|
||||
async fn process_get_account_balance(&self, request: Request) -> Result<Value, RpcErr> {
|
||||
@ -153,8 +171,7 @@ impl JsonHandler {
|
||||
let balance = {
|
||||
let state = self.sequencer_state.lock().await;
|
||||
state.store.acc_store.get_account_balance(&address)
|
||||
}
|
||||
.unwrap_or(0);
|
||||
};
|
||||
|
||||
let helperstruct = GetAccountBalanceResponse { balance };
|
||||
|
||||
@ -187,6 +204,7 @@ impl JsonHandler {
|
||||
GET_BLOCK => self.process_get_block_data(request).await,
|
||||
GET_GENESIS => self.process_get_genesis(request).await,
|
||||
GET_LAST_BLOCK => self.process_get_last_block(request).await,
|
||||
GET_INITIAL_TESTNET_ACCOUNTS => self.get_initial_testnet_accounts(request).await,
|
||||
GET_ACCOUNT_BALANCE => self.process_get_account_balance(request).await,
|
||||
GET_TRANSACTION_BY_HASH => self.process_get_transaction_by_hash(request).await,
|
||||
_ => Err(RpcErr(RpcError::method_not_found(request.method))),
|
||||
@ -199,14 +217,12 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{rpc_handler, JsonHandler};
|
||||
use accounts::account_core::Account;
|
||||
use common::{
|
||||
rpc_primitives::RpcPollingConfig,
|
||||
transaction::{SignaturePrivateKey, Transaction, TransactionBody},
|
||||
};
|
||||
use sequencer_core::{
|
||||
config::{AccountInitialData, SequencerConfig},
|
||||
SequencerCore,
|
||||
};
|
||||
use sequencer_core::{config::SequencerConfig, SequencerCore};
|
||||
use serde_json::Value;
|
||||
use tempfile::tempdir;
|
||||
use tokio::sync::Mutex;
|
||||
@ -214,16 +230,243 @@ mod tests {
|
||||
fn sequencer_config_for_tests() -> SequencerConfig {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let home = tempdir.path().to_path_buf();
|
||||
let initial_accounts = vec![
|
||||
AccountInitialData {
|
||||
addr: "cafe".repeat(16).to_string(),
|
||||
balance: 100,
|
||||
let initial_acc1 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"balance": 100,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718",
|
||||
"pub_account_signing_key": [
|
||||
244,
|
||||
88,
|
||||
134,
|
||||
61,
|
||||
35,
|
||||
209,
|
||||
229,
|
||||
101,
|
||||
85,
|
||||
35,
|
||||
140,
|
||||
140,
|
||||
192,
|
||||
226,
|
||||
83,
|
||||
83,
|
||||
190,
|
||||
189,
|
||||
110,
|
||||
8,
|
||||
89,
|
||||
127,
|
||||
147,
|
||||
142,
|
||||
157,
|
||||
204,
|
||||
51,
|
||||
109,
|
||||
189,
|
||||
92,
|
||||
144,
|
||||
68
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4"
|
||||
},
|
||||
AccountInitialData {
|
||||
addr: "feca".repeat(16).to_string(),
|
||||
balance: 200,
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506",
|
||||
"viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF"
|
||||
},
|
||||
];
|
||||
"viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_acc2 = serde_json::from_str(r#"{
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"balance": 200,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271",
|
||||
"pub_account_signing_key": [
|
||||
136,
|
||||
105,
|
||||
9,
|
||||
53,
|
||||
180,
|
||||
145,
|
||||
64,
|
||||
5,
|
||||
235,
|
||||
174,
|
||||
62,
|
||||
211,
|
||||
206,
|
||||
116,
|
||||
185,
|
||||
24,
|
||||
214,
|
||||
62,
|
||||
244,
|
||||
64,
|
||||
224,
|
||||
59,
|
||||
120,
|
||||
150,
|
||||
30,
|
||||
249,
|
||||
160,
|
||||
46,
|
||||
189,
|
||||
254,
|
||||
47,
|
||||
244
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179"
|
||||
},
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122",
|
||||
"viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7"
|
||||
},
|
||||
"viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99"
|
||||
},
|
||||
"utxos": {}
|
||||
}"#).unwrap();
|
||||
|
||||
let initial_accounts = vec![initial_acc1, initial_acc2];
|
||||
|
||||
SequencerConfig {
|
||||
home,
|
||||
@ -237,9 +480,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn json_handler_for_tests() -> JsonHandler {
|
||||
fn json_handler_for_tests() -> (JsonHandler, Vec<Account>) {
|
||||
let config = sequencer_config_for_tests();
|
||||
|
||||
let mut sequencer_core = SequencerCore::start_from_config(config);
|
||||
let initial_accounts = sequencer_core
|
||||
.sequencer_config
|
||||
.initial_accounts
|
||||
.iter()
|
||||
.map(|acc_ser| acc_ser.clone().into())
|
||||
.collect();
|
||||
|
||||
let tx_body = TransactionBody {
|
||||
tx_kind: common::transaction::TxKind::Public,
|
||||
execution_input: Default::default(),
|
||||
@ -265,10 +516,15 @@ mod tests {
|
||||
.produce_new_block_with_mempool_transactions()
|
||||
.unwrap();
|
||||
|
||||
let sequencer_core = Arc::new(Mutex::new(sequencer_core));
|
||||
|
||||
(
|
||||
JsonHandler {
|
||||
polling_config: RpcPollingConfig::default(),
|
||||
sequencer_state: Arc::new(Mutex::new(sequencer_core)),
|
||||
}
|
||||
sequencer_state: sequencer_core,
|
||||
},
|
||||
initial_accounts,
|
||||
)
|
||||
}
|
||||
|
||||
async fn call_rpc_handler_with_json(handler: JsonHandler, request_json: Value) -> Value {
|
||||
@ -294,7 +550,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_account_balance_for_non_existent_account() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_account_balance",
|
||||
@ -316,7 +572,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_account_balance_for_invalid_hex() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_account_balance",
|
||||
@ -339,7 +595,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_account_balance_for_invalid_length() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_account_balance",
|
||||
@ -362,11 +618,14 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_account_balance_for_existing_account() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, initial_accounts) = json_handler_for_tests();
|
||||
|
||||
let acc1_addr = hex::encode(initial_accounts[0].address);
|
||||
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_account_balance",
|
||||
"params": { "address": "cafe".repeat(16) },
|
||||
"params": { "address": acc1_addr },
|
||||
"id": 1
|
||||
});
|
||||
let expected_response = serde_json::json!({
|
||||
@ -384,7 +643,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_transaction_by_hash_for_non_existent_hash() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_transaction_by_hash",
|
||||
@ -406,7 +665,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_transaction_by_hash_for_invalid_hex() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_transaction_by_hash",
|
||||
@ -430,7 +689,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_transaction_by_hash_for_invalid_length() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_transaction_by_hash",
|
||||
@ -454,7 +713,7 @@ mod tests {
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_transaction_by_hash_for_existing_transaction() {
|
||||
let json_handler = json_handler_for_tests();
|
||||
let (json_handler, _) = json_handler_for_tests();
|
||||
let request = serde_json::json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "get_transaction_by_hash",
|
||||
|
||||
@ -8,12 +8,238 @@
|
||||
"port": 3040,
|
||||
"initial_accounts": [
|
||||
{
|
||||
"addr": "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c",
|
||||
"balance": 10
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"balance": 100,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
244,
|
||||
55,
|
||||
238,
|
||||
205,
|
||||
74,
|
||||
115,
|
||||
179,
|
||||
192,
|
||||
65,
|
||||
186,
|
||||
166,
|
||||
169,
|
||||
221,
|
||||
45,
|
||||
6,
|
||||
57,
|
||||
200,
|
||||
65,
|
||||
195,
|
||||
70,
|
||||
118,
|
||||
252,
|
||||
206,
|
||||
100,
|
||||
215,
|
||||
250,
|
||||
72,
|
||||
230,
|
||||
19,
|
||||
71,
|
||||
217,
|
||||
249
|
||||
],
|
||||
"nullifer_public_key": "03A340BECA9FAAB444CED0140681D72EA1318B5C611704FEE017DA9836B17DB718",
|
||||
"pub_account_signing_key": [
|
||||
244,
|
||||
88,
|
||||
134,
|
||||
61,
|
||||
35,
|
||||
209,
|
||||
229,
|
||||
101,
|
||||
85,
|
||||
35,
|
||||
140,
|
||||
140,
|
||||
192,
|
||||
226,
|
||||
83,
|
||||
83,
|
||||
190,
|
||||
189,
|
||||
110,
|
||||
8,
|
||||
89,
|
||||
127,
|
||||
147,
|
||||
142,
|
||||
157,
|
||||
204,
|
||||
51,
|
||||
109,
|
||||
189,
|
||||
92,
|
||||
144,
|
||||
68
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "7BC46784DB1BC67825D8F029436846712BFDF9B5D79EA3AB11D39A52B9B229D4"
|
||||
},
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "BB54A8D3C9C51B82C431082D1845A74677B0EF829A11B517E1D9885DE3139506",
|
||||
"viewing_secret_key": "AD923E92F6A5683E30140CEAB2702AFB665330C1EE4EFA70FAF29767B6B52BAF"
|
||||
},
|
||||
"viewing_public_key": "0361220C5D277E7A1709340FD31A52600C1432B9C45B9BCF88A43581D58824A8B6"
|
||||
},
|
||||
"utxos": {}
|
||||
},
|
||||
{
|
||||
"addr": "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31",
|
||||
"balance": 100
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"balance": 1000,
|
||||
"key_holder": {
|
||||
"address": [
|
||||
72,
|
||||
169,
|
||||
70,
|
||||
237,
|
||||
1,
|
||||
96,
|
||||
35,
|
||||
157,
|
||||
25,
|
||||
15,
|
||||
83,
|
||||
18,
|
||||
52,
|
||||
206,
|
||||
202,
|
||||
63,
|
||||
48,
|
||||
59,
|
||||
173,
|
||||
76,
|
||||
78,
|
||||
7,
|
||||
254,
|
||||
229,
|
||||
28,
|
||||
45,
|
||||
194,
|
||||
79,
|
||||
6,
|
||||
89,
|
||||
58,
|
||||
85
|
||||
],
|
||||
"nullifer_public_key": "02172F50274DE67C4087C344F5D58E11DF761D90285B095060E0994FAA6BCDE271",
|
||||
"pub_account_signing_key": [
|
||||
136,
|
||||
105,
|
||||
9,
|
||||
53,
|
||||
180,
|
||||
145,
|
||||
64,
|
||||
5,
|
||||
235,
|
||||
174,
|
||||
62,
|
||||
211,
|
||||
206,
|
||||
116,
|
||||
185,
|
||||
24,
|
||||
214,
|
||||
62,
|
||||
244,
|
||||
64,
|
||||
224,
|
||||
59,
|
||||
120,
|
||||
150,
|
||||
30,
|
||||
249,
|
||||
160,
|
||||
46,
|
||||
189,
|
||||
254,
|
||||
47,
|
||||
244
|
||||
],
|
||||
"top_secret_key_holder": {
|
||||
"secret_spending_key": "80A186737C8D38B4288A03F0F589957D9C040D79C19F3E0CC4BA80F8494E5179"
|
||||
},
|
||||
"utxo_secret_key_holder": {
|
||||
"nullifier_secret_key": "746928E63F0984F6F4818933493CE9C067562D9CB932FDC06D82C86CDF6D7122",
|
||||
"viewing_secret_key": "89176CF4BC9E673807643FD52110EF99D4894335AFB10D881AC0B5041FE1FCB7"
|
||||
},
|
||||
"viewing_public_key": "026072A8F83FEC3472E30CDD4767683F30B91661D25B1040AD9A5FC2E01D659F99"
|
||||
},
|
||||
"utxos": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user