fix: fixes and retrieval methods

This commit is contained in:
Oleksandr Pravdyvyi 2025-07-23 15:16:53 +03:00
parent 9f8724ee4c
commit 5b2af29efd
No known key found for this signature in database
GPG Key ID: 9F8955C63C443871
11 changed files with 157 additions and 162 deletions

1
Cargo.lock generated
View File

@ -4363,6 +4363,7 @@ dependencies = [
name = "sequencer_rpc" name = "sequencer_rpc"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"accounts",
"actix", "actix",
"actix-cors", "actix-cors",
"actix-web", "actix-web",

View File

@ -34,12 +34,16 @@ pub struct GetGenesisIdRequest {}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct GetLastBlockRequest {} pub struct GetLastBlockRequest {}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetInitialTestnetAccountsRequest {}
parse_request!(HelloRequest); parse_request!(HelloRequest);
parse_request!(RegisterAccountRequest); parse_request!(RegisterAccountRequest);
parse_request!(SendTxRequest); parse_request!(SendTxRequest);
parse_request!(GetBlockDataRequest); parse_request!(GetBlockDataRequest);
parse_request!(GetGenesisIdRequest); parse_request!(GetGenesisIdRequest);
parse_request!(GetLastBlockRequest); parse_request!(GetLastBlockRequest);
parse_request!(GetInitialTestnetAccountsRequest);
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HelloResponse { pub struct HelloResponse {

View File

@ -103,7 +103,14 @@ impl NodeCore {
let genesis_block = client.get_block(genesis_id.genesis_id).await?.block; 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)?; 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?; pre_start::setup_empty_sc_states(&storage).await?;

View File

@ -1,8 +1,8 @@
use accounts::account_core::Account; use accounts::account_core::{Account, AccountForSerialization};
use anyhow::Result; use anyhow::Result;
use common::rpc_primitives::requests::{ use common::rpc_primitives::requests::{
GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse,
RegisterAccountRequest, RegisterAccountResponse, GetInitialTestnetAccountsRequest, RegisterAccountRequest, RegisterAccountResponse,
}; };
use common::transaction::Transaction; use common::transaction::Transaction;
use common::{SequencerClientError, SequencerRpcError}; use common::{SequencerClientError, SequencerRpcError};
@ -121,4 +121,21 @@ impl SequencerClient {
Ok(resp_deser) 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)
}
} }

View File

@ -6,8 +6,6 @@ use std::path::PathBuf;
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
///Helperstruct for account serialization ///Helperstruct for account serialization
pub struct AccountInitialData { pub struct AccountInitialData {
///Hex encoded `AccountAddress`
pub addr: String,
pub balance: u64, pub balance: u64,
} }
@ -27,6 +25,6 @@ pub struct SequencerConfig {
pub block_create_timeout_millis: u64, pub block_create_timeout_millis: u64,
///Port to listen ///Port to listen
pub port: u16, pub port: u16,
///List of pairs (account_address, initial_balance) ///List of initial accounts data
pub initial_accounts: Vec<AccountInitialData>, pub initial_accounts: Vec<AccountInitialData>,
} }

View File

@ -38,7 +38,6 @@ pub enum TransactionMalformationErrorKind {
ChainStateFurtherThanTransactionState { tx: TreeHashType }, ChainStateFurtherThanTransactionState { tx: TreeHashType },
FailedToInsert { tx: TreeHashType, details: String }, FailedToInsert { tx: TreeHashType, details: String },
InvalidSignature, InvalidSignature,
AccountNotFound { tx: TreeHashType, acc: TreeHashType },
BalanceMismatch { tx: TreeHashType }, BalanceMismatch { tx: TreeHashType },
FailedToDecode { tx: TreeHashType }, FailedToDecode { tx: TreeHashType },
} }
@ -110,41 +109,26 @@ impl SequencerCore {
if let Ok(native_transfer_action) = if let Ok(native_transfer_action) =
serde_json::from_slice::<PublicNativeTokenSend>(&execution_input) serde_json::from_slice::<PublicNativeTokenSend>(&execution_input)
{ {
if let Some(from_balance) = self let from_balance = self
.store .store
.acc_store .acc_store
.get_account_balance(&native_transfer_action.from) .get_account_balance(&native_transfer_action.from);
{ let to_balance = self
if let Some(to_balance) = self .store
.store .acc_store
.acc_store .get_account_balance(&native_transfer_action.to);
.get_account_balance(&native_transfer_action.to)
{ if from_balance >= native_transfer_action.moved_balance {
if from_balance >= native_transfer_action.moved_balance { self.store.acc_store.set_account_balance(
self.store.acc_store.set_account_balance( &native_transfer_action.from,
&native_transfer_action.from, from_balance - native_transfer_action.moved_balance,
from_balance - native_transfer_action.moved_balance, );
); self.store.acc_store.set_account_balance(
self.store.acc_store.set_account_balance( &native_transfer_action.to,
&native_transfer_action.to, to_balance + native_transfer_action.moved_balance,
to_balance + native_transfer_action.moved_balance, );
);
} else {
return Err(TransactionMalformationErrorKind::BalanceMismatch {
tx: tx_hash,
});
}
} else {
return Err(TransactionMalformationErrorKind::AccountNotFound {
tx: tx_hash,
acc: native_transfer_action.to,
});
}
} else { } else {
return Err(TransactionMalformationErrorKind::AccountNotFound { return Err(TransactionMalformationErrorKind::BalanceMismatch { tx: tx_hash });
tx: tx_hash,
acc: native_transfer_action.from,
});
} }
} else { } else {
return Err(TransactionMalformationErrorKind::FailedToDecode { tx: tx_hash }); return Err(TransactionMalformationErrorKind::FailedToDecode { tx: tx_hash });
@ -347,16 +331,8 @@ mod tests {
fn setup_sequencer_config() -> SequencerConfig { fn setup_sequencer_config() -> SequencerConfig {
let initial_accounts = vec![ let initial_accounts = vec![
AccountInitialData { AccountInitialData { balance: 10 },
addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c" AccountInitialData { balance: 100 },
.to_string(),
balance: 10,
},
AccountInitialData {
addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31"
.to_string(),
balance: 100,
},
]; ];
setup_sequencer_config_variable_initial_accounts(initial_accounts) setup_sequencer_config_variable_initial_accounts(initial_accounts)
@ -409,53 +385,27 @@ mod tests {
assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10); assert_eq!(sequencer.sequencer_config.max_num_tx_in_block, 10);
assert_eq!(sequencer.sequencer_config.port, 8080); assert_eq!(sequencer.sequencer_config.port, 8080);
let acc1_addr: [u8; 32] = hex::decode( let acc1_addr = sequencer.store.testnet_initial_accounts_full_data[0].address;
"bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c".to_string(), let acc2_addr = sequencer.store.testnet_initial_accounts_full_data[1].address;
)
.unwrap()
.try_into()
.unwrap();
let acc2_addr: [u8; 32] = hex::decode(
"20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31".to_string(),
)
.unwrap()
.try_into()
.unwrap();
assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
assert_eq!( assert_eq!(
10, 10,
sequencer sequencer.store.acc_store.get_account_balance(&acc1_addr)
.store
.acc_store
.get_account_balance(&acc1_addr)
.unwrap()
); );
assert_eq!( assert_eq!(
100, 100,
sequencer sequencer.store.acc_store.get_account_balance(&acc2_addr)
.store
.acc_store
.get_account_balance(&acc2_addr)
.unwrap()
); );
} }
#[test] #[test]
fn test_start_different_intial_accounts() { fn test_start_different_intial_accounts() {
let initial_accounts = vec![ let initial_accounts = vec![
AccountInitialData { AccountInitialData { balance: 1000 },
addr: "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff" AccountInitialData { balance: 1000 },
.to_string(),
balance: 1000,
},
AccountInitialData {
addr: "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff"
.to_string(),
balance: 1000,
},
]; ];
let intial_accounts_len = initial_accounts.len(); let intial_accounts_len = initial_accounts.len();
@ -463,18 +413,8 @@ mod tests {
let config = setup_sequencer_config_variable_initial_accounts(initial_accounts); let config = setup_sequencer_config_variable_initial_accounts(initial_accounts);
let sequencer = SequencerCore::start_from_config(config.clone()); let sequencer = SequencerCore::start_from_config(config.clone());
let acc1_addr: [u8; 32] = hex::decode( let acc1_addr = sequencer.store.testnet_initial_accounts_full_data[0].address;
"bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117ffffff".to_string(), let acc2_addr = sequencer.store.testnet_initial_accounts_full_data[1].address;
)
.unwrap()
.try_into()
.unwrap();
let acc2_addr: [u8; 32] = hex::decode(
"20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1effffff".to_string(),
)
.unwrap()
.try_into()
.unwrap();
assert!(sequencer.store.acc_store.contains_account(&acc1_addr)); assert!(sequencer.store.acc_store.contains_account(&acc1_addr));
assert!(sequencer.store.acc_store.contains_account(&acc2_addr)); assert!(sequencer.store.acc_store.contains_account(&acc2_addr));
@ -483,19 +423,11 @@ mod tests {
assert_eq!( assert_eq!(
1000, 1000,
sequencer sequencer.store.acc_store.get_account_balance(&acc1_addr)
.store
.acc_store
.get_account_balance(&acc1_addr)
.unwrap()
); );
assert_eq!( assert_eq!(
1000, 1000,
sequencer sequencer.store.acc_store.get_account_balance(&acc2_addr)
.store
.acc_store
.get_account_balance(&acc2_addr)
.unwrap()
); );
} }

View File

@ -1,4 +1,4 @@
use accounts::account_core::AccountAddress; use accounts::account_core::{Account, AccountAddress};
use anyhow::Result; use anyhow::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -28,13 +28,13 @@ pub struct SequencerAccountsStore {
} }
impl SequencerAccountsStore { impl SequencerAccountsStore {
pub fn new(initial_accounts: &[(AccountAddress, u64)]) -> Self { pub fn new(initial_accounts: &[Account]) -> Self {
let mut accounts = HashMap::new(); let mut accounts = HashMap::new();
for (account_addr, balance) in initial_accounts { for account in initial_accounts {
accounts.insert( accounts.insert(
*account_addr, account.address,
AccountPublicData::new_with_balance(*account_addr, *balance), AccountPublicData::new_with_balance(account.address, account.balance),
); );
} }
@ -56,28 +56,29 @@ impl SequencerAccountsStore {
///Check `account_addr` balance, ///Check `account_addr` balance,
/// ///
///returns `None`, if account address not found ///returns 0, if account address not found
pub fn get_account_balance(&self, account_addr: &AccountAddress) -> Option<u64> { pub fn get_account_balance(&self, account_addr: &AccountAddress) -> u64 {
self.accounts.get(account_addr).map(|acc| acc.balance) self.accounts
.get(account_addr)
.map(|acc| acc.balance)
.unwrap_or(0)
} }
///Update `account_addr` balance, ///Update `account_addr` balance,
/// ///
/// returns `None` if account address not found, othervise returns previous balance /// returns 0, if account address not found, othervise returns previous balance
pub fn set_account_balance( pub fn set_account_balance(&mut self, account_addr: &AccountAddress, new_balance: u64) -> u64 {
&mut self,
account_addr: &AccountAddress,
new_balance: u64,
) -> Option<u64> {
let acc_data = self.accounts.get_mut(account_addr); let acc_data = self.accounts.get_mut(account_addr);
acc_data.map(|data| { acc_data
let old_bal = data.balance; .map(|data| {
let old_bal = data.balance;
data.balance = new_balance; data.balance = new_balance;
old_bal old_bal
}) })
.unwrap_or(0)
} }
///Remove account from storage ///Remove account from storage
@ -89,14 +90,10 @@ impl SequencerAccountsStore {
&mut self, &mut self,
account_addr: AccountAddress, account_addr: AccountAddress,
) -> Result<Option<AccountAddress>> { ) -> Result<Option<AccountAddress>> {
if let Some(account_balance) = self.get_account_balance(&account_addr) { if self.get_account_balance(&account_addr) == 0 {
if account_balance == 0 { Ok(self.accounts.remove(&account_addr).map(|data| data.address))
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 { } else {
Ok(None) anyhow::bail!("Chain consistency violation: It is forbidden to remove account with nonzero balance");
} }
} }
@ -147,7 +144,7 @@ mod tests {
assert!(seq_acc_store.contains_account(&[1; 32])); 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); assert_eq!(acc_balance, 0);
} }
@ -165,9 +162,14 @@ mod tests {
#[test] #[test]
fn account_sequencer_store_unregister_acc_not_zero_balance() { fn account_sequencer_store_unregister_acc_not_zero_balance() {
let mut seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); let acc1 = Account::new_with_balance(12);
let acc2 = Account::new_with_balance(100);
let rem_res = seq_acc_store.unregister_account([1; 32]); let acc1_addr = acc1.address.clone();
let mut seq_acc_store = SequencerAccountsStore::new(&[acc1, acc2]);
let rem_res = seq_acc_store.unregister_account(acc1_addr);
assert!(rem_res.is_err()); assert!(rem_res.is_err());
} }
@ -187,49 +189,65 @@ mod tests {
#[test] #[test]
fn account_sequencer_store_with_preset_accounts_1() { fn account_sequencer_store_with_preset_accounts_1() {
let seq_acc_store = SequencerAccountsStore::new(&[([1; 32], 12), ([2; 32], 100)]); let acc1 = Account::new_with_balance(12);
let acc2 = Account::new_with_balance(100);
assert!(seq_acc_store.contains_account(&[1; 32])); let acc1_addr = acc1.address.clone();
assert!(seq_acc_store.contains_account(&[2; 32])); let acc2_addr = acc2.address.clone();
let acc_balance = seq_acc_store.get_account_balance(&[1; 32]).unwrap(); let seq_acc_store = SequencerAccountsStore::new(&[acc1, acc2]);
assert!(seq_acc_store.contains_account(&acc1_addr));
assert!(seq_acc_store.contains_account(&acc2_addr));
let acc_balance = seq_acc_store.get_account_balance(&acc1_addr);
assert_eq!(acc_balance, 12); 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(&acc2_addr);
assert_eq!(acc_balance, 100); assert_eq!(acc_balance, 100);
} }
#[test] #[test]
fn account_sequencer_store_with_preset_accounts_2() { fn account_sequencer_store_with_preset_accounts_2() {
let seq_acc_store = let acc1 = Account::new_with_balance(120);
SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); let acc2 = Account::new_with_balance(15);
let acc3 = Account::new_with_balance(10);
assert!(seq_acc_store.contains_account(&[6; 32])); let acc1_addr = acc1.address.clone();
assert!(seq_acc_store.contains_account(&[7; 32])); let acc2_addr = acc2.address.clone();
assert!(seq_acc_store.contains_account(&[8; 32])); let acc3_addr = acc3.address.clone();
let acc_balance = seq_acc_store.get_account_balance(&[6; 32]).unwrap(); let seq_acc_store = SequencerAccountsStore::new(&[acc1, acc2, acc3]);
assert!(seq_acc_store.contains_account(&acc1_addr));
assert!(seq_acc_store.contains_account(&acc2_addr));
assert!(seq_acc_store.contains_account(&acc3_addr));
let acc_balance = seq_acc_store.get_account_balance(&[6; 32]);
assert_eq!(acc_balance, 120); 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); 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); assert_eq!(acc_balance, 10);
} }
#[test] #[test]
fn account_sequencer_store_fetch_unknown_account() { fn account_sequencer_store_fetch_unknown_account() {
let seq_acc_store = let acc1 = Account::new_with_balance(120);
SequencerAccountsStore::new(&[([6; 32], 120), ([7; 32], 15), ([8; 32], 10)]); let acc2 = Account::new_with_balance(15);
let acc3 = Account::new_with_balance(10);
let seq_acc_store = SequencerAccountsStore::new(&[acc1, acc2, acc3]);
let acc_balance = seq_acc_store.get_account_balance(&[9; 32]); let acc_balance = seq_acc_store.get_account_balance(&[9; 32]);
assert!(acc_balance.is_none()); assert_eq!(acc_balance, 0);
} }
} }

View File

@ -1,5 +1,6 @@
use std::{collections::HashSet, path::Path}; use std::{collections::HashSet, path::Path};
use accounts::account_core::Account;
use accounts_store::SequencerAccountsStore; use accounts_store::SequencerAccountsStore;
use block_store::SequecerBlockStore; use block_store::SequecerBlockStore;
use common::{ use common::{
@ -20,6 +21,8 @@ pub struct SequecerChainStore {
pub nullifier_store: HashSet<UTXONullifier>, pub nullifier_store: HashSet<UTXONullifier>,
pub utxo_commitments_store: UTXOCommitmentsMerkleTree, pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
pub pub_tx_store: PublicTransactionMerkleTree, pub pub_tx_store: PublicTransactionMerkleTree,
//ToDo: For testing purposes, remove after testnet
pub testnet_initial_accounts_full_data: Vec<Account>,
} }
impl SequecerChainStore { impl SequecerChainStore {
@ -29,22 +32,12 @@ impl SequecerChainStore {
is_genesis_random: bool, is_genesis_random: bool,
initial_accounts: &[AccountInitialData], initial_accounts: &[AccountInitialData],
) -> Self { ) -> Self {
let acc_data_decoded: Vec<([u8; 32], u64)> = initial_accounts let accs_pregenerated: Vec<Account> = initial_accounts
.iter() .iter()
.map(|acc_data| { .map(|acc_data| Account::new_with_balance(acc_data.balance))
(
//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,
)
})
.collect(); .collect();
let acc_store = SequencerAccountsStore::new(&acc_data_decoded); let acc_store = SequencerAccountsStore::new(&accs_pregenerated);
let nullifier_store = HashSet::new(); let nullifier_store = HashSet::new();
let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]); let utxo_commitments_store = UTXOCommitmentsMerkleTree::new(vec![]);
let pub_tx_store = PublicTransactionMerkleTree::new(vec![]); let pub_tx_store = PublicTransactionMerkleTree::new(vec![]);
@ -81,6 +74,7 @@ impl SequecerChainStore {
nullifier_store, nullifier_store,
utxo_commitments_store, utxo_commitments_store,
pub_tx_store, pub_tx_store,
testnet_initial_accounts_full_data: accs_pregenerated,
} }
} }
} }

View File

@ -20,6 +20,9 @@ tokio.workspace = true
[dependencies.mempool] [dependencies.mempool]
path = "../mempool" path = "../mempool"
[dependencies.accounts]
path = "../accounts"
[dependencies.consensus] [dependencies.consensus]
path = "../consensus" path = "../consensus"

View File

@ -1,3 +1,4 @@
use accounts::account_core::AccountForSerialization;
use actix_web::Error as HttpError; use actix_web::Error as HttpError;
use serde_json::Value; use serde_json::Value;
@ -5,6 +6,7 @@ use common::rpc_primitives::{
errors::RpcError, errors::RpcError,
message::{Message, Request}, message::{Message, Request},
parser::RpcRequest, parser::RpcRequest,
requests::GetInitialTestnetAccountsRequest,
}; };
use common::rpc_primitives::requests::{ use common::rpc_primitives::requests::{
@ -26,6 +28,8 @@ pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER";
pub const SUCCESS: &str = "Success"; pub const SUCCESS: &str = "Success";
pub const GET_INITIAL_TESTNET_ACCOUNTS: &str = "get_initial_testnet_accounts";
impl JsonHandler { impl JsonHandler {
pub async fn process(&self, message: Message) -> Result<Message, HttpError> { pub async fn process(&self, message: Message) -> Result<Message, HttpError> {
let id = message.id(); let id = message.id();
@ -131,6 +135,24 @@ impl JsonHandler {
respond(helperstruct) respond(helperstruct)
} }
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
.store
.testnet_initial_accounts_full_data
.iter()
.map(|acc| acc.clone().into())
.collect()
};
respond(accounts_for_serialization)
}
pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> { pub async fn process_request_internal(&self, request: Request) -> Result<Value, RpcErr> {
match request.method.as_ref() { match request.method.as_ref() {
HELLO => self.process_temp_hello(request).await, HELLO => self.process_temp_hello(request).await,
@ -139,6 +161,7 @@ impl JsonHandler {
GET_BLOCK => self.process_get_block_data(request).await, GET_BLOCK => self.process_get_block_data(request).await,
GET_GENESIS => self.process_get_genesis(request).await, GET_GENESIS => self.process_get_genesis(request).await,
GET_LAST_BLOCK => self.process_get_last_block(request).await, GET_LAST_BLOCK => self.process_get_last_block(request).await,
GET_INITIAL_TESTNET_ACCOUNTS => self.get_initial_testnet_accounts(request).await,
_ => Err(RpcErr(RpcError::method_not_found(request.method))), _ => Err(RpcErr(RpcError::method_not_found(request.method))),
} }
} }

View File

@ -8,11 +8,9 @@
"port": 3040, "port": 3040,
"initial_accounts": [ "initial_accounts": [
{ {
"addr": "bfd91e6703273a115ad7f099ef32f621243be69369d00ddef5d3a25117d09a8c",
"balance": 10 "balance": 10
}, },
{ {
"addr": "20573479053979b98d2ad09ef31a0750f22c77709bed51c4e64946bd1e376f31",
"balance": 100 "balance": 100
} }
] ]