Skip to content

Commit

Permalink
GH-728: Finish the password-change logic (#355)
Browse files Browse the repository at this point in the history
* GH-728: add the TODOs

* GH-728: removed the code of the NewPasswordMessage

* GH-728: use ConfigurationChangeMessage while changing password

* GH-728: rename configuration_change_msg_sub_opt to update_min_hops_sub_opt

* GH-728: rename new_password_subs to update_password_subs

* GH-728: fix wrong name for the actor message

* GH-728: send ConfigurationChangeMessage to other actors too

* GH-728: add a TODO

* GH-728: rename to _opt

* GH-728: implement handler for ConfigurationChange::UpdatePassword inside Neighborhood

* GH-728: add TODO to implement handler for ConfigurationChange::UpdatePassword inside BlockchainBridge

* GH-728: add TODO to implement handler for ConfigurationChange::UpdatePassword inside Accountant

* GH-728: create new struct for UpdatePasswordSubs

* GH-728: add the new TODO

* GH-728: send a ConfigurtionChangeMessage when the consuming wallet is generated

* GH-728: add a test for the panic case

* GH-728: some refactor changes in configurator.rs

* GH-728: test drive the case when the wallet is recovered

* GH-728: fix some of the tests

* GH-728: fix the remaining 2 failing tests

* GH-728: reorder fields

* GH-728: the received ConfigurationChangeMessage is properly handled

* GH-728: update the password when necessary

* GH-728: add a todo

* GH-728: add the ability to synchronise password

* GH-728: add ability for accountant to handle an unexpected configuration change msg

* GH-728: improve tests for handling ConfigurationChangeMessage in accountant

* GH-728: minor renames

* GH-728: remove finished TODO and formatting changes

* GH-728: add test in blockchain bridge for ConfigurationChangeMessage

* GH-728: add test in neighborhood for ConfigurationChangeMessage

* GH-728: remove useless tests

* GH-728: revive an old test

* GH-728: improve todo

* GH-728: test rename and add more TODOs

* GH-728: cleanup and creation of new file configuration_change_subs.rs

* GH-728: minor refactor and remove tests

* GH-728: introduce trait for ConfigurationChangesubs

* GH-728: refactor out the subs for UpdateWallets and UpdatePassword

* GH-728: some renames

* GH-728: add TODO and minor reordering

* GH-728: make the test the_password_is_synchronised_among_other_actors_when_modified stronger

* GH-728: add formatting changes

* GH-728: make enum usage more explicit

* GH-728: remove clippy warnings

* GH-728: do some renames

* GH-728: fix wrong rename and import

* GH-728: use peer actors for generating config change subs

* GH-728: recreate ConfigChangeSubs

* GH-728: remove config_change_subs.rs

* GH-728: test for ConfigChangeMsg in Accountant contain assertions

* GH-728: test for ConfigChangeMsg in Neighborhood contain assertions

* GH-728: test for ConfigChangeMsg in BlockchainBridge contain assertions

* GH-728: small rename

* GH-728: add context_id to fn

* GH-728: refactor the fn to transform associated functions to methods

* GH-728: minor fixes

* GH-728: add wallet_opt as a new argument in the begin_scan fn

* GH-728: remove the use of field consuming_wallet_opt from BlockchainBridge

* GH-728: remove the field consuming_wallet_opt from BlockchainBridge

* GH-728: don't send the ConfigChangeMsg to the BlockchainBridge

* GH-728: use the earning wallet in Receivable Scanner's begin_scan

* GH-728: don't save a reference of earning wallet inside Scanners

* GH-728: store the earning wallet directly without an Rc

* GH-728: fix the failing test

* GH-728: formatting changes

* GH-728: remove the earning wallet from ReceivableScannerBuilder

* GH-728: check wallet in the begin_scan() for ScannerMock

* GH-728: remove unnecessary TODO

* GH-728: formatting changes

* GH-728: fix the failing test

* GH-728: remove unused import in blockchain_interaction_test.rs

* GH-728: BlockchainBridge receives consuming_wallet instead of an Option<T>

* GH-728: Check consuming wallet before sending a msg to BlockchainBridge

* GH-728: remove Option<T> from the wallet_opt param in begin_scan fn

* GH-728: remove commented out code

* GH-728: modify AccountantBuilder to make it's field names contain opt

* GH-728: improve test mocks

* GH-728: introduce another URL for mumbai testnet

* GH-728: change the message in trace log

* GH-728: test drive the NoConsumingWallet Error

* GH-728: reordering

* GH-728: add better logging

* GH-728: Review 2 changes

* GH-728: Review 2 leftover changes

* GH-728: add better assertions for logger
  • Loading branch information
utkarshg6 authored May 29, 2024
1 parent 40480d1 commit 2007ccd
Show file tree
Hide file tree
Showing 15 changed files with 727 additions and 561 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::path::PathBuf;
use std::time::{Duration, SystemTime};

use log::Level;
use regex::escape;
use serde_derive::Serialize;

use masq_lib::messages::{FromMessageBody, ScanType, ToMessageBody, UiScanRequest, UiScanResponse};
Expand Down Expand Up @@ -157,19 +156,15 @@ fn blockchain_bridge_starts_properly_on_bootstrap() {
let mut cluster = MASQNodeCluster::start().unwrap();
let private_key = "0011223300112233001122330011223300112233001122330011223300112233";
let subject = cluster.start_real_node(
NodeStartupConfigBuilder::zero_hop()
NodeStartupConfigBuilder::standard()
.consuming_wallet_info(ConsumingWalletInfo::PrivateKey(private_key.to_string()))
.chain(cluster.chain)
.build(),
);

let escaped_pattern = escape(&format!(
"DEBUG: BlockchainBridge: Received BindMessage; consuming wallet address {}",
subject.consuming_wallet().unwrap()
));
MASQNodeUtils::wrote_log_containing(
subject.name(),
&escaped_pattern,
"DEBUG: BlockchainBridge: Received BindMessage",
Duration::from_millis(1000),
)
}
Expand Down
295 changes: 267 additions & 28 deletions node/src/accountant/mod.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@

use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent;
use crate::accountant::{ResponseSkeleton, SkeletonOptHolder};
use crate::sub_lib::wallet::Wallet;
use actix::Message;
use masq_lib::type_obfuscation::Obfuscated;
use std::fmt::Debug;

#[derive(Debug, Message, PartialEq, Eq, Clone)]
pub struct QualifiedPayablesMessage {
pub protected_qualified_payables: Obfuscated,
pub consuming_wallet: Wallet,
pub response_skeleton_opt: Option<ResponseSkeleton>,
}

impl QualifiedPayablesMessage {
pub(in crate::accountant) fn new(
protected_qualified_payables: Obfuscated,
consuming_wallet: Wallet,
response_skeleton_opt: Option<ResponseSkeleton>,
) -> Self {
Self {
protected_qualified_payables,
consuming_wallet,
response_skeleton_opt,
}
}
Expand Down
93 changes: 59 additions & 34 deletions node/src/accountant/scanners/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ impl Scanners {
pub fn new(
dao_factories: DaoFactories,
payment_thresholds: Rc<PaymentThresholds>,
earning_wallet: Rc<Wallet>,
when_pending_too_long_sec: u64,
financial_statistics: Rc<RefCell<FinancialStatistics>>,
) -> Self {
Expand All @@ -94,7 +93,6 @@ impl Scanners {
dao_factories.banned_dao_factory.make(),
Box::new(persistent_configuration),
Rc::clone(&payment_thresholds),
earning_wallet,
financial_statistics,
));

Expand All @@ -113,6 +111,7 @@ where
{
fn begin_scan(
&mut self,
wallet: Wallet,
timestamp: SystemTime,
response_skeleton_opt: Option<ResponseSkeleton>,
logger: &Logger,
Expand Down Expand Up @@ -193,6 +192,7 @@ pub struct PayableScanner {
impl Scanner<QualifiedPayablesMessage, SentPayables> for PayableScanner {
fn begin_scan(
&mut self,
consuming_wallet: Wallet,
timestamp: SystemTime,
response_skeleton_opt: Option<ResponseSkeleton>,
logger: &Logger,
Expand Down Expand Up @@ -225,8 +225,11 @@ impl Scanner<QualifiedPayablesMessage, SentPayables> for PayableScanner {
qualified_payables.len()
);
let protected_payables = self.protect_payables(qualified_payables);
let outgoing_msg =
QualifiedPayablesMessage::new(protected_payables, response_skeleton_opt);
let outgoing_msg = QualifiedPayablesMessage::new(
protected_payables,
consuming_wallet,
response_skeleton_opt,
);
Ok(outgoing_msg)
}
}
Expand Down Expand Up @@ -567,6 +570,7 @@ pub struct PendingPayableScanner {
impl Scanner<RequestTransactionReceipts, ReportTransactionReceipts> for PendingPayableScanner {
fn begin_scan(
&mut self,
_irrelevant_wallet: Wallet,
timestamp: SystemTime,
response_skeleton_opt: Option<ResponseSkeleton>,
logger: &Logger,
Expand Down Expand Up @@ -825,13 +829,13 @@ pub struct ReceivableScanner {
pub receivable_dao: Box<dyn ReceivableDao>,
pub banned_dao: Box<dyn BannedDao>,
pub persistent_configuration: Box<dyn PersistentConfiguration>,
pub earning_wallet: Rc<Wallet>,
pub financial_statistics: Rc<RefCell<FinancialStatistics>>,
}

impl Scanner<RetrieveTransactions, ReceivedPayments> for ReceivableScanner {
fn begin_scan(
&mut self,
earning_wallet: Wallet,
timestamp: SystemTime,
response_skeleton_opt: Option<ResponseSkeleton>,
logger: &Logger,
Expand All @@ -840,14 +844,11 @@ impl Scanner<RetrieveTransactions, ReceivedPayments> for ReceivableScanner {
return Err(BeginScanError::ScanAlreadyRunning(timestamp));
}
self.mark_as_started(timestamp);
info!(
logger,
"Scanning for receivables to {}", self.earning_wallet
);
info!(logger, "Scanning for receivables to {}", earning_wallet);
self.scan_for_delinquencies(timestamp, logger);

Ok(RetrieveTransactions {
recipient: self.earning_wallet.as_ref().clone(),
recipient: earning_wallet,
response_skeleton_opt,
})
}
Expand Down Expand Up @@ -893,12 +894,10 @@ impl ReceivableScanner {
banned_dao: Box<dyn BannedDao>,
persistent_configuration: Box<dyn PersistentConfiguration>,
payment_thresholds: Rc<PaymentThresholds>,
earning_wallet: Rc<Wallet>,
financial_statistics: Rc<RefCell<FinancialStatistics>>,
) -> Self {
Self {
common: ScannerCommon::new(payment_thresholds),
earning_wallet,
receivable_dao,
banned_dao,
persistent_configuration,
Expand Down Expand Up @@ -985,6 +984,7 @@ impl ReceivableScanner {
#[derive(Debug, PartialEq, Eq)]
pub enum BeginScanError {
NothingToProcess,
NoConsumingWalletFound,
ScanAlreadyRunning(SystemTime),
CalledFromNullScanner, // Exclusive for tests
}
Expand All @@ -1007,6 +1007,10 @@ impl BeginScanError {
scan_type,
BeginScanError::timestamp_as_string(timestamp)
)),
BeginScanError::NoConsumingWalletFound => Some(format!(
"Cannot initiate {:?} scan because no consuming wallet was found.",
scan_type
)),
BeginScanError::CalledFromNullScanner => match cfg!(test) {
true => None,
false => panic!("Null Scanner shouldn't be running inside production code."),
Expand Down Expand Up @@ -1134,9 +1138,9 @@ mod tests {
DaoFactories, FinancialStatistics, PaymentThresholds, ScanIntervals,
DEFAULT_PAYMENT_THRESHOLDS,
};
use crate::test_utils::make_wallet;
use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock;
use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp;
use crate::test_utils::{make_paying_wallet, make_wallet};
use actix::{Message, System};
use ethereum_types::U64;
use masq_lib::logger::Logger;
Expand Down Expand Up @@ -1175,7 +1179,6 @@ mod tests {
total_paid_payable_wei: 1,
total_paid_receivable_wei: 2,
};
let earning_wallet = make_wallet("unique_wallet");
let payment_thresholds = make_custom_payment_thresholds();
let payment_thresholds_rc = Rc::new(payment_thresholds);
let initial_rc_count = Rc::strong_count(&payment_thresholds_rc);
Expand All @@ -1189,7 +1192,6 @@ mod tests {
config_dao_factory: Box::new(config_dao_factory),
},
Rc::clone(&payment_thresholds_rc),
Rc::new(earning_wallet.clone()),
when_pending_too_long_sec,
Rc::new(RefCell::new(financial_statistics.clone())),
);
Expand Down Expand Up @@ -1234,10 +1236,6 @@ mod tests {
*receivable_scanner.financial_statistics.borrow(),
financial_statistics
);
assert_eq!(
receivable_scanner.earning_wallet.address(),
earning_wallet.address()
);
assert_eq!(
receivable_scanner.common.payment_thresholds.as_ref(),
&payment_thresholds
Expand Down Expand Up @@ -1274,6 +1272,7 @@ mod tests {
fn payable_scanner_can_initiate_a_scan() {
init_test_logging();
let test_name = "payable_scanner_can_initiate_a_scan";
let consuming_wallet = make_paying_wallet(b"consuming wallet");
let now = SystemTime::now();
let (qualified_payable_accounts, _, all_non_pending_payables) =
make_payables(now, &PaymentThresholds::default());
Expand All @@ -1283,7 +1282,8 @@ mod tests {
.payable_dao(payable_dao)
.build();

let result = subject.begin_scan(now, None, &Logger::new(test_name));
let result =
subject.begin_scan(consuming_wallet.clone(), now, None, &Logger::new(test_name));

let timestamp = subject.scan_started_at();
assert_eq!(timestamp, Some(now));
Expand All @@ -1293,6 +1293,7 @@ mod tests {
protected_qualified_payables: protect_payables_in_test(
qualified_payable_accounts.clone()
),
consuming_wallet,
response_skeleton_opt: None,
})
);
Expand All @@ -1307,16 +1308,22 @@ mod tests {

#[test]
fn payable_scanner_throws_error_when_a_scan_is_already_running() {
let consuming_wallet = make_paying_wallet(b"consuming wallet");
let now = SystemTime::now();
let (_, _, all_non_pending_payables) = make_payables(now, &PaymentThresholds::default());
let payable_dao =
PayableDaoMock::new().non_pending_payables_result(all_non_pending_payables);
let mut subject = PayableScannerBuilder::new()
.payable_dao(payable_dao)
.build();
let _result = subject.begin_scan(now, None, &Logger::new("test"));
let _result = subject.begin_scan(consuming_wallet.clone(), now, None, &Logger::new("test"));

let run_again_result = subject.begin_scan(SystemTime::now(), None, &Logger::new("test"));
let run_again_result = subject.begin_scan(
consuming_wallet,
SystemTime::now(),
None,
&Logger::new("test"),
);

let is_scan_running = subject.scan_started_at().is_some();
assert_eq!(is_scan_running, true);
Expand All @@ -1328,6 +1335,7 @@ mod tests {

#[test]
fn payable_scanner_throws_error_in_case_no_qualified_payable_is_found() {
let consuming_wallet = make_paying_wallet(b"consuming wallet");
let now = SystemTime::now();
let (_, unqualified_payable_accounts, _) =
make_payables(now, &PaymentThresholds::default());
Expand All @@ -1337,7 +1345,7 @@ mod tests {
.payable_dao(payable_dao)
.build();

let result = subject.begin_scan(now, None, &Logger::new("test"));
let result = subject.begin_scan(consuming_wallet, now, None, &Logger::new("test"));

let is_scan_running = subject.scan_started_at().is_some();
assert_eq!(is_scan_running, false);
Expand Down Expand Up @@ -2210,6 +2218,7 @@ mod tests {
fn pending_payable_scanner_can_initiate_a_scan() {
init_test_logging();
let test_name = "pending_payable_scanner_can_initiate_a_scan";
let consuming_wallet = make_paying_wallet(b"consuming wallet");
let now = SystemTime::now();
let payable_fingerprint_1 = PendingPayableFingerprint {
rowid: 555,
Expand All @@ -2234,7 +2243,12 @@ mod tests {
.pending_payable_dao(pending_payable_dao)
.build();

let result = pending_payable_scanner.begin_scan(now, None, &Logger::new(test_name));
let result = pending_payable_scanner.begin_scan(
consuming_wallet,
now,
None,
&Logger::new(test_name),
);

let no_of_pending_payables = fingerprints.len();
let is_scan_running = pending_payable_scanner.scan_started_at().is_some();
Expand All @@ -2257,6 +2271,7 @@ mod tests {
#[test]
fn pending_payable_scanner_throws_error_in_case_scan_is_already_running() {
let now = SystemTime::now();
let consuming_wallet = make_paying_wallet(b"consuming");
let pending_payable_dao = PendingPayableDaoMock::new()
.return_all_errorless_fingerprints_result(vec![PendingPayableFingerprint {
rowid: 1234,
Expand All @@ -2270,9 +2285,9 @@ mod tests {
.pending_payable_dao(pending_payable_dao)
.build();
let logger = Logger::new("test");
let _ = subject.begin_scan(now, None, &logger);
let _ = subject.begin_scan(consuming_wallet.clone(), now, None, &logger);

let result = subject.begin_scan(SystemTime::now(), None, &logger);
let result = subject.begin_scan(consuming_wallet, SystemTime::now(), None, &logger);

let is_scan_running = subject.scan_started_at().is_some();
assert_eq!(is_scan_running, true);
Expand All @@ -2282,13 +2297,15 @@ mod tests {
#[test]
fn pending_payable_scanner_throws_an_error_when_no_fingerprint_is_found() {
let now = SystemTime::now();
let consuming_wallet = make_paying_wallet(b"consuming_wallet");
let pending_payable_dao =
PendingPayableDaoMock::new().return_all_errorless_fingerprints_result(vec![]);
let mut pending_payable_scanner = PendingPayableScannerBuilder::new()
.pending_payable_dao(pending_payable_dao)
.build();

let result = pending_payable_scanner.begin_scan(now, None, &Logger::new("test"));
let result =
pending_payable_scanner.begin_scan(consuming_wallet, now, None, &Logger::new("test"));

let is_scan_running = pending_payable_scanner.scan_started_at().is_some();
assert_eq!(result, Err(BeginScanError::NothingToProcess));
Expand Down Expand Up @@ -2924,10 +2941,14 @@ mod tests {
let earning_wallet = make_wallet("earning");
let mut receivable_scanner = ReceivableScannerBuilder::new()
.receivable_dao(receivable_dao)
.earning_wallet(earning_wallet.clone())
.build();

let result = receivable_scanner.begin_scan(now, None, &Logger::new(test_name));
let result = receivable_scanner.begin_scan(
earning_wallet.clone(),
now,
None,
&Logger::new(test_name),
);

let is_scan_running = receivable_scanner.scan_started_at().is_some();
assert_eq!(is_scan_running, true);
Expand All @@ -2952,11 +2973,16 @@ mod tests {
let earning_wallet = make_wallet("earning");
let mut receivable_scanner = ReceivableScannerBuilder::new()
.receivable_dao(receivable_dao)
.earning_wallet(earning_wallet)
.build();
let _ = receivable_scanner.begin_scan(now, None, &Logger::new("test"));
let _ =
receivable_scanner.begin_scan(earning_wallet.clone(), now, None, &Logger::new("test"));

let result = receivable_scanner.begin_scan(SystemTime::now(), None, &Logger::new("test"));
let result = receivable_scanner.begin_scan(
earning_wallet,
SystemTime::now(),
None,
&Logger::new("test"),
);

let is_scan_running = receivable_scanner.scan_started_at().is_some();
assert_eq!(is_scan_running, true);
Expand Down Expand Up @@ -2989,12 +3015,11 @@ mod tests {
.receivable_dao(receivable_dao)
.banned_dao(banned_dao)
.payment_thresholds(payment_thresholds)
.earning_wallet(earning_wallet.clone())
.build();
let logger = Logger::new("DELINQUENCY_TEST");
let now = SystemTime::now();

let result = receivable_scanner.begin_scan(now, None, &logger);
let result = receivable_scanner.begin_scan(earning_wallet.clone(), now, None, &logger);

assert_eq!(
result,
Expand Down
Loading

0 comments on commit 2007ccd

Please sign in to comment.