Skip to content

Commit

Permalink
GH-606: Initialize start_block to none to use latest block
Browse files Browse the repository at this point in the history
  • Loading branch information
masqrauder committed Mar 31, 2024
1 parent 79e34c3 commit 26fe492
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 118 deletions.
13 changes: 8 additions & 5 deletions masq/src/commands/configuration_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ impl ConfigurationCommand {
dump_parameter_line(
stream,
"Start block:",
&configuration.start_block.to_string(),
&configuration
.start_block_opt
.map(|m| m.separate_with_commas())
.unwrap_or_else(|| "[Latest]".to_string()),
);
Self::dump_value_list(stream, "Past neighbors:", &configuration.past_neighbors);
let payment_thresholds = Self::preprocess_combined_parameters({
Expand Down Expand Up @@ -333,7 +336,7 @@ mod tests {
exit_byte_rate: 129000000,
exit_service_rate: 160000000,
},
start_block: 3456,
start_block_opt: None,
scan_intervals: UiScanIntervals {
pending_payable_sec: 150500,
payable_sec: 155000,
Expand Down Expand Up @@ -378,7 +381,7 @@ mod tests {
|Max block count: [Unlimited]\n\
|Neighborhood mode: standard\n\
|Port mapping protocol: PCP\n\
|Start block: 3456\n\
|Start block: [Latest]\n\
|Past neighbors: neighbor 1\n\
| neighbor 2\n\
|Payment thresholds: \n\
Expand Down Expand Up @@ -433,7 +436,7 @@ mod tests {
exit_byte_rate: 20,
exit_service_rate: 30,
},
start_block: 3456,
start_block_opt: Some(1234567890u64),
scan_intervals: UiScanIntervals {
pending_payable_sec: 1000,
payable_sec: 1000,
Expand Down Expand Up @@ -476,7 +479,7 @@ mod tests {
|Max block count: 100,000\n\
|Neighborhood mode: zero-hop\n\
|Port mapping protocol: PCP\n\
|Start block: 3456\n\
|Start block: 1,234,567,890\n\
|Past neighbors: [?]\n\
|Payment thresholds: \n\
| Debt threshold: 2,500 gwei\n\
Expand Down
15 changes: 10 additions & 5 deletions masq/src/commands/set_configuration_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ impl SetConfigurationCommand {
}

fn validate_start_block(start_block: String) -> Result<(), String> {
match start_block.parse::<u64>() {
Ok(_) => Ok(()),
_ => Err(start_block),
if "none".eq_ignore_ascii_case(&start_block) {
Ok(())
} else {
match start_block.parse::<u64>() {
Ok(_) => Ok(()),
_ => Err(start_block),
}
}
}

Expand All @@ -59,7 +63,7 @@ impl Command for SetConfigurationCommand {
const SET_CONFIGURATION_ABOUT: &str =
"Sets Node configuration parameters being enabled for this operation when the Node is running.";
const START_BLOCK_HELP: &str =
"Ordinal number of the Ethereum block where scanning for transactions will start.";
"Ordinal number of the Ethereum block where scanning for transactions will start. Use 'none' for Latest block.";

pub fn set_configurationify<'a>(shared_schema_arg: Arg<'a, 'a>) -> Arg<'a, 'a> {
shared_schema_arg.takes_value(true).min_values(1)
Expand Down Expand Up @@ -103,7 +107,7 @@ mod tests {
);
assert_eq!(
START_BLOCK_HELP,
"Ordinal number of the Ethereum block where scanning for transactions will start."
"Ordinal number of the Ethereum block where scanning for transactions will start. Use 'none' for Latest block."
);
}

Expand All @@ -126,6 +130,7 @@ mod tests {
fn validate_start_block_works() {
assert!(validate_start_block("abc".to_string()).is_err());
assert!(validate_start_block("1566".to_string()).is_ok());
assert!(validate_start_block("none".to_string()).is_ok());
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion masq_lib/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::data_version::DataVersion;
use const_format::concatcp;

pub const DEFAULT_CHAIN: Chain = Chain::PolyMainnet;
pub const CURRENT_SCHEMA_VERSION: usize = 9;
pub const CURRENT_SCHEMA_VERSION: usize = 10;

pub const HIGHEST_RANDOM_CLANDESTINE_PORT: u16 = 9999;
pub const HTTP_PORT: u16 = 80;
Expand Down
2 changes: 1 addition & 1 deletion masq_lib/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ pub struct UiConfigurationResponse {
#[serde(rename = "portMappingProtocol")]
pub port_mapping_protocol_opt: Option<String>,
#[serde(rename = "startBlock")]
pub start_block: u64,
pub start_block_opt: Option<u64>,
#[serde(rename = "consumingWalletPrivateKeyOpt")]
pub consuming_wallet_private_key_opt: Option<String>,
// This item is calculated from the private key, not stored in the database, so that
Expand Down
105 changes: 86 additions & 19 deletions node/src/blockchain/blockchain_bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,9 @@ impl BlockchainBridge {

fn handle_retrieve_transactions(&mut self, msg: RetrieveTransactions) -> Result<(), String> {
let start_block_nbr = match self.persistent_config.start_block() {
Ok (sb) => sb,
Err (e) => panic! ("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e)
Ok(Some(sb)) => sb,
Ok(None) => u64::MAX,
Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e)
};
let max_block_count = match self.persistent_config.max_block_count() {
Ok(Some(mbc)) => mbc,
Expand All @@ -314,30 +315,46 @@ impl BlockchainBridge {
.get_block_number()
{
Ok(eb) => {
if u64::MAX == max_block_count {
if u64::MAX == max_block_count || u64::MAX == start_block_nbr {
BlockNumber::Number(eb)
} else {
BlockNumber::Number(eb.as_u64().min(start_block_nbr + max_block_count).into())
}
}
Err(e) => {
info!(
self.logger,
"Using 'latest' block number instead of a literal number. {:?}", e
);
if max_block_count == u64::MAX {
info!(
self.logger,
"Using 'latest' block number instead of a literal number. {:?}", e
);
BlockNumber::Latest
} else if u64::MAX == start_block_nbr {
BlockNumber::Latest
} else {
BlockNumber::Number((start_block_nbr + max_block_count).into())
}
}
};
let start_block = BlockNumber::Number(start_block_nbr.into());
let start_block = if u64::MAX == start_block_nbr {
end_block
} else {
BlockNumber::Number(start_block_nbr.into())
};
let retrieved_transactions =
self.blockchain_interface
.retrieve_transactions(start_block, end_block, &msg.recipient);
match retrieved_transactions {
Ok(transactions) => {
debug!(
self.logger,
"Write new start block: {}", transactions.new_start_block
);
if let Err(e) = self
.persistent_config
.set_start_block(Some(transactions.new_start_block))
{
panic! ("Cannot set start block {} in database; payments to you may not be processed: {:?}", transactions.new_start_block, e)
};
if transactions.transactions.is_empty() {
debug!(self.logger, "No new receivable detected");
}
Expand Down Expand Up @@ -1123,7 +1140,7 @@ mod tests {
.lower_interface_results(Box::new(lower_interface));
let persistent_config = PersistentConfigurationMock::new()
.max_block_count_result(Ok(Some(100_000)))
.start_block_result(Ok(5)); // no set_start_block_result: set_start_block() must not be called
.start_block_result(Ok(Some(5))); // no set_start_block_result: set_start_block() must not be called
let mut subject = BlockchainBridge::new(
Box::new(blockchain_interface),
Box::new(persistent_config),
Expand Down Expand Up @@ -1409,17 +1426,20 @@ mod tests {
},
],
};
let lower_interface =
LowBlockchainIntMock::default().get_block_number_result(LatestBlockNumber::Err(
BlockchainError::QueryFailed("Failed to read the latest block number".to_string()),
));
let lower_interface = LowBlockchainIntMock::default().get_block_number_result(
LatestBlockNumber::Err(BlockchainError::QueryFailed(
"\"Failed to read the latest block number\"".to_string(),
)),
);
let blockchain_interface_mock = BlockchainInterfaceMock::default()
.retrieve_transactions_params(&retrieve_transactions_params_arc)
.retrieve_transactions_result(Ok(expected_transactions.clone()))
.lower_interface_results(Box::new(lower_interface));
let persistent_config = PersistentConfigurationMock::new()
.max_block_count_result(Ok(Some(10000u64)))
.start_block_result(Ok(6));
.max_block_count_result(Ok(None))
.start_block_result(Ok(Some(6)))
.set_start_block_params(&set_start_block_params_arc)
.set_start_block_result(Ok(()));
let subject = BlockchainBridge::new(
Box::new(blockchain_interface_mock),
Box::new(persistent_config),
Expand All @@ -1444,12 +1464,14 @@ mod tests {
System::current().stop();
system.run();
let after = SystemTime::now();
let set_start_block_params = set_start_block_params_arc.lock().unwrap();
assert_eq!(*set_start_block_params, vec![Some(8675309u64)]);
let retrieve_transactions_params = retrieve_transactions_params_arc.lock().unwrap();
assert_eq!(
*retrieve_transactions_params,
vec![(
BlockNumber::Number(6u64.into()),
BlockNumber::Number(10006u64.into()),
BlockNumber::Latest,
earning_wallet
)]
);
Expand All @@ -1469,7 +1491,9 @@ mod tests {
}),
}
);
TestLogHandler::new().exists_log_containing("INFO: BlockchainBridge: Using 'latest' block number instead of a literal number. QueryFailed(\"Failed to read the latest block number\")");
TestLogHandler::new().exists_log_containing(
"INFO: BlockchainBridge: Using 'latest' block number instead of a literal number.",
);
}

#[test]
Expand Down Expand Up @@ -1505,7 +1529,9 @@ mod tests {
.lower_interface_results(Box::new(lower_interface));
let persistent_config = PersistentConfigurationMock::new()
.max_block_count_result(Ok(Some(10000u64)))
.start_block_result(Ok(6));
.start_block_result(Ok(Some(6)))
.set_start_block_params(&set_start_block_params_arc)
.set_start_block_result(Ok(()));
let subject = BlockchainBridge::new(
Box::new(blockchain_interface_mock),
Box::new(persistent_config),
Expand All @@ -1530,6 +1556,8 @@ mod tests {
System::current().stop();
system.run();
let after = SystemTime::now();
let set_start_block_params = set_start_block_params_arc.lock().unwrap();
assert_eq!(*set_start_block_params, vec![Some(1234u64)]);
let retrieve_transactions_params = retrieve_transactions_params_arc.lock().unwrap();
assert_eq!(
*retrieve_transactions_params,
Expand Down Expand Up @@ -1570,7 +1598,9 @@ mod tests {
.lower_interface_results(Box::new(lower_interface));
let persistent_config = PersistentConfigurationMock::new()
.max_block_count_result(Ok(Some(10000u64)))
.start_block_result(Ok(6));
.start_block_result(Ok(Some(6)))
.set_start_block_params(&set_start_block_params_arc)
.set_start_block_result(Ok(()));
let (accountant, _, accountant_recording_arc) = make_recorder();
let system = System::new(
"processing_of_received_payments_continues_even_if_no_payments_are_detected",
Expand Down Expand Up @@ -1599,6 +1629,8 @@ mod tests {
System::current().stop();
system.run();
let after = SystemTime::now();
let set_start_block_params = set_start_block_params_arc.lock().unwrap();
assert_eq!(*set_start_block_params, vec![Some(7)]);
let accountant_received_payment = accountant_recording_arc.lock().unwrap();
let received_payments = accountant_received_payment.get_record::<ReceivedPayments>(0);
check_timestamp(before, received_payments.timestamp, after);
Expand Down Expand Up @@ -1643,6 +1675,41 @@ mod tests {
let _ = subject.handle_retrieve_transactions(retrieve_transactions);
}

#[test]
#[should_panic(
expected = "Cannot set start block 1234 in database; payments to you may not be processed: TransactionError"
)]
fn handle_retrieve_transactions_panics_if_start_block_cannot_be_written() {
let persistent_config = PersistentConfigurationMock::new()
.start_block_result(Ok(Some(1234)))
.max_block_count_result(Ok(Some(10000u64)))
.set_start_block_result(Err(PersistentConfigError::TransactionError));
let lower_interface =
LowBlockchainIntMock::default().get_block_number_result(Ok(0u64.into()));
let blockchain_interface = BlockchainInterfaceMock::default()
.retrieve_transactions_result(Ok(RetrievedBlockchainTransactions {
new_start_block: 1234,
transactions: vec![BlockchainTransaction {
block_number: 1000,
from: make_wallet("somewallet"),
wei_amount: 2345,
}],
}))
.lower_interface_results(Box::new(lower_interface));
let mut subject = BlockchainBridge::new(
Box::new(blockchain_interface),
Box::new(persistent_config),
false,
None, //not needed in this test
);
let retrieve_transactions = RetrieveTransactions {
recipient: make_wallet("somewallet"),
response_skeleton_opt: None,
};

let _ = subject.handle_retrieve_transactions(retrieve_transactions);
}

fn success_handler(
_bcb: &mut BlockchainBridge,
_msg: RetrieveTransactions,
Expand Down
25 changes: 10 additions & 15 deletions node/src/database/config_dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,8 @@ mod tests {
);
assert_value("neighborhoodMode", "zero-hop", &map);
assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map);
assert_value(
"startBlock",
&Chain::PolyMainnet.rec().contract_creation_block.to_string(),
&map,
);
assert!(map.contains_key("startBlock"));
assert_none("startBlock", &map);
assert_value(
"exampleEncrypted",
&dao.get("example_encrypted").unwrap().value_opt.unwrap(),
Expand Down Expand Up @@ -503,11 +500,8 @@ mod tests {
assert_value("pastNeighbors", "masq://polygon-mainnet:QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU@1.2.3.4:1234,masq://polygon-mainnet:QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY@2.3.4.5:2345", &map);
assert_value("neighborhoodMode", "consume-only", &map);
assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map);
assert_value(
"startBlock",
&Chain::PolyMainnet.rec().contract_creation_block.to_string(),
&map,
);
assert!(map.contains_key("startBlock"));
assert_none("startBlock", &map);
let expected_ee_entry = dao.get("example_encrypted").unwrap().value_opt.unwrap();
let expected_ee_decrypted = Bip39::decrypt_bytes(&expected_ee_entry, "password").unwrap();
let expected_ee_string = encode_bytes(Some(expected_ee_decrypted)).unwrap().unwrap();
Expand Down Expand Up @@ -620,11 +614,8 @@ mod tests {
);
assert_value("neighborhoodMode", "standard", &map);
assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map);
assert_value(
"startBlock",
&Chain::PolyMainnet.rec().contract_creation_block.to_string(),
&map,
);
assert!(map.contains_key("startBlock"));
assert_none("startBlock", &map);
assert_value(
"exampleEncrypted",
&dao.get("example_encrypted").unwrap().value_opt.unwrap(),
Expand Down Expand Up @@ -679,6 +670,10 @@ mod tests {
assert_eq!(actual_value, expected_value);
}

fn assert_none(key: &str, map: &Map<String, Value>) {
assert!(!map.get(key).is_none());
}

fn assert_encrypted_value(
key: &str,
expected_value: &str,
Expand Down
Loading

0 comments on commit 26fe492

Please sign in to comment.