diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index 84f4f11..e852672 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -161,7 +161,7 @@ impl NodeChainStore { } } else { let native_transfer = - serde_json::from_slice::(&tx.execution_input); + serde_json::from_slice::(&tx.body().execution_input); if let Ok(transfer) = native_transfer { if let Some(acc_sender) = self.acc_map.get_mut(&transfer.from) { diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 03334b7..71538bc 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -3,7 +3,9 @@ use std::sync::{ Arc, }; -use common::{transaction::Transaction, ExecutionFailureKind}; +use common::{ + public_transfer_receipts::PublicNativeTokenSend, transaction::Transaction, ExecutionFailureKind, +}; use accounts::{ account_core::{Account, AccountAddress}, @@ -977,7 +979,7 @@ impl NodeCore { let new_len = 0; let state_changes = (serde_json::to_value(state_changes).unwrap(), new_len); - let tx: Transaction = + let tx: TransactionBody = sc_core::transaction_payloads_tools::create_public_transaction_payload( serde_json::to_vec(&PublicNativeTokenSend { from, @@ -994,7 +996,24 @@ impl NodeCore { .into(); tx.log(); - Ok(self.sequencer_client.send_tx(tx, tx_roots).await?) + { + 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( diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 40ff1a2..761d5a1 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -6,6 +6,7 @@ use common::{ block::{Block, HashableBlockData}, merkle_tree_public::TreeHashType, nullifier::UTXONullifier, + public_transfer_receipts::PublicNativeTokenSend, transaction::{AuthenticatedTransaction, Transaction, TransactionBody, TxKind}, utxo_commitment::UTXOCommitment, }; @@ -37,6 +38,9 @@ pub enum TransactionMalformationErrorKind { ChainStateFurtherThanTransactionState { tx: TreeHashType }, FailedToInsert { tx: TreeHashType, details: String }, InvalidSignature, + AccountNotFound { tx: TreeHashType, acc: TreeHashType }, + BalanceMismatch { tx: TreeHashType }, + FailedToDecode { tx: TreeHashType }, } impl Display for TransactionMalformationErrorKind { @@ -102,6 +106,50 @@ impl SequencerCore { ); } + //Balance check + if let Ok(native_transfer_action) = + serde_json::from_slice::(&execution_input) + { + if let Some(from_balance) = self + .store + .acc_store + .get_account_balance(&native_transfer_action.from) + { + if let Some(to_balance) = self + .store + .acc_store + .get_account_balance(&native_transfer_action.to) + { + if from_balance >= native_transfer_action.moved_balance { + self.store.acc_store.set_account_balance( + &native_transfer_action.from, + from_balance - native_transfer_action.moved_balance, + ); + self.store.acc_store.set_account_balance( + &native_transfer_action.to, + 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 { + return Err(TransactionMalformationErrorKind::AccountNotFound { + tx: tx_hash, + acc: native_transfer_action.from, + }); + } + } else { + return Err(TransactionMalformationErrorKind::FailedToDecode { tx: tx_hash }); + } + //Sanity check match tx_kind { TxKind::Public => { diff --git a/sequencer_core/src/sequencer_store/accounts_store.rs b/sequencer_core/src/sequencer_store/accounts_store.rs index 853247f..48cd012 100644 --- a/sequencer_core/src/sequencer_store/accounts_store.rs +++ b/sequencer_core/src/sequencer_store/accounts_store.rs @@ -61,6 +61,25 @@ impl SequencerAccountsStore { self.accounts.get(account_addr).map(|acc| acc.balance) } + ///Update `account_addr` balance, + /// + /// returns `None` if account address not found, othervise returns previous balance + pub fn set_account_balance( + &mut self, + account_addr: &AccountAddress, + new_balance: u64, + ) -> Option { + let acc_data = self.accounts.get_mut(account_addr); + + acc_data.map(|data| { + let old_bal = data.balance; + + data.balance = new_balance; + + old_bal + }) + } + ///Remove account from storage /// /// Fails, if `balance` is != 0