mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
Less cloning and pattern simplifications (#3305)
* Cleanup * Pattern simplification
This commit is contained in:
parent
6556dd585d
commit
be4779c923
32 changed files with 183 additions and 226 deletions
|
@ -144,7 +144,7 @@ impl OutputHandler {
|
||||||
"Failure to get output for commitment {} with error {}",
|
"Failure to get output for commitment {} with error {}",
|
||||||
commit, e
|
commit, e
|
||||||
);
|
);
|
||||||
return Err(e.into());
|
return Err(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ impl OutputHandler {
|
||||||
"Failure to get output for commitment {} with error {}",
|
"Failure to get output for commitment {} with error {}",
|
||||||
x, e
|
x, e
|
||||||
);
|
);
|
||||||
return Err(e.into());
|
return Err(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub fn get_output_v2(
|
||||||
|
|
||||||
let output_printable = OutputPrintable::from_output(
|
let output_printable = OutputPrintable::from_output(
|
||||||
&output,
|
&output,
|
||||||
chain.clone(),
|
chain,
|
||||||
header.as_ref(),
|
header.as_ref(),
|
||||||
include_proof,
|
include_proof,
|
||||||
include_merkle_proof,
|
include_merkle_proof,
|
||||||
|
|
|
@ -344,9 +344,7 @@ impl OutputPrintable {
|
||||||
let p_vec = util::from_hex(&proof_str)
|
let p_vec = util::from_hex(&proof_str)
|
||||||
.map_err(|_| ser::Error::HexError("invalid output range_proof".to_string()))?;
|
.map_err(|_| ser::Error::HexError("invalid output range_proof".to_string()))?;
|
||||||
let mut p_bytes = [0; util::secp::constants::MAX_PROOF_SIZE];
|
let mut p_bytes = [0; util::secp::constants::MAX_PROOF_SIZE];
|
||||||
for i in 0..p_bytes.len() {
|
p_bytes.clone_from_slice(&p_vec[..util::secp::constants::MAX_PROOF_SIZE]);
|
||||||
p_bytes[i] = p_vec[i];
|
|
||||||
}
|
|
||||||
Ok(pedersen::RangeProof {
|
Ok(pedersen::RangeProof {
|
||||||
proof: p_bytes,
|
proof: p_bytes,
|
||||||
plen: p_bytes.len(),
|
plen: p_bytes.len(),
|
||||||
|
|
|
@ -585,8 +585,8 @@ impl Chain {
|
||||||
let previous_header = batch.get_previous_header(&b.header)?;
|
let previous_header = batch.get_previous_header(&b.header)?;
|
||||||
pipe::rewind_and_apply_fork(&previous_header, ext, batch)?;
|
pipe::rewind_and_apply_fork(&previous_header, ext, batch)?;
|
||||||
|
|
||||||
let ref mut extension = ext.extension;
|
let extension = &mut ext.extension;
|
||||||
let ref mut header_extension = ext.header_extension;
|
let header_extension = &mut ext.header_extension;
|
||||||
|
|
||||||
// Retrieve the header root before we apply the new block
|
// Retrieve the header root before we apply the new block
|
||||||
let prev_root = header_extension.root()?;
|
let prev_root = header_extension.root()?;
|
||||||
|
@ -1451,7 +1451,7 @@ fn setup_head(
|
||||||
let res = txhashset::extending(header_pmmr, txhashset, &mut batch, |ext, batch| {
|
let res = txhashset::extending(header_pmmr, txhashset, &mut batch, |ext, batch| {
|
||||||
pipe::rewind_and_apply_fork(&header, ext, batch)?;
|
pipe::rewind_and_apply_fork(&header, ext, batch)?;
|
||||||
|
|
||||||
let ref mut extension = ext.extension;
|
let extension = &mut ext.extension;
|
||||||
|
|
||||||
extension.validate_roots(&header)?;
|
extension.validate_roots(&header)?;
|
||||||
|
|
||||||
|
|
|
@ -118,9 +118,9 @@ pub fn process_block(b: &Block, ctx: &mut BlockContext<'_>) -> Result<Option<Tip
|
||||||
|
|
||||||
// Start a chain extension unit of work dependent on the success of the
|
// Start a chain extension unit of work dependent on the success of the
|
||||||
// internal validation and saving operations
|
// internal validation and saving operations
|
||||||
let ref mut header_pmmr = &mut ctx.header_pmmr;
|
let header_pmmr = &mut ctx.header_pmmr;
|
||||||
let ref mut txhashset = &mut ctx.txhashset;
|
let txhashset = &mut ctx.txhashset;
|
||||||
let ref mut batch = &mut ctx.batch;
|
let batch = &mut ctx.batch;
|
||||||
txhashset::extending(header_pmmr, txhashset, batch, |ext, batch| {
|
txhashset::extending(header_pmmr, txhashset, batch, |ext, batch| {
|
||||||
rewind_and_apply_fork(&prev, ext, batch)?;
|
rewind_and_apply_fork(&prev, ext, batch)?;
|
||||||
|
|
||||||
|
@ -399,8 +399,8 @@ fn verify_coinbase_maturity(
|
||||||
ext: &txhashset::ExtensionPair<'_>,
|
ext: &txhashset::ExtensionPair<'_>,
|
||||||
batch: &store::Batch<'_>,
|
batch: &store::Batch<'_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let ref extension = ext.extension;
|
let extension = &ext.extension;
|
||||||
let ref header_extension = ext.header_extension;
|
let header_extension = &ext.header_extension;
|
||||||
extension
|
extension
|
||||||
.utxo_view(header_extension)
|
.utxo_view(header_extension)
|
||||||
.verify_coinbase_maturity(&block.inputs(), block.header.height, batch)
|
.verify_coinbase_maturity(&block.inputs(), block.header.height, batch)
|
||||||
|
@ -541,8 +541,8 @@ pub fn rewind_and_apply_fork(
|
||||||
ext: &mut txhashset::ExtensionPair<'_>,
|
ext: &mut txhashset::ExtensionPair<'_>,
|
||||||
batch: &store::Batch<'_>,
|
batch: &store::Batch<'_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let ref mut extension = ext.extension;
|
let extension = &mut ext.extension;
|
||||||
let ref mut header_extension = ext.header_extension;
|
let header_extension = &mut ext.header_extension;
|
||||||
|
|
||||||
// Prepare the header MMR.
|
// Prepare the header MMR.
|
||||||
rewind_and_apply_header_fork(header, header_extension, batch)?;
|
rewind_and_apply_header_fork(header, header_extension, batch)?;
|
||||||
|
@ -592,8 +592,8 @@ fn validate_utxo(
|
||||||
ext: &mut txhashset::ExtensionPair<'_>,
|
ext: &mut txhashset::ExtensionPair<'_>,
|
||||||
batch: &store::Batch<'_>,
|
batch: &store::Batch<'_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let ref mut extension = ext.extension;
|
let extension = &ext.extension;
|
||||||
let ref mut header_extension = ext.header_extension;
|
let header_extension = &ext.header_extension;
|
||||||
extension
|
extension
|
||||||
.utxo_view(header_extension)
|
.utxo_view(header_extension)
|
||||||
.validate_block(block, batch)
|
.validate_block(block, batch)
|
||||||
|
|
|
@ -377,7 +377,7 @@ impl<'a> Batch<'a> {
|
||||||
{
|
{
|
||||||
Ok(Bitmap::deserialize(&bytes))
|
Ok(Bitmap::deserialize(&bytes))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFoundErr("legacy block input bitmap".to_string()).into())
|
Err(Error::NotFoundErr("legacy block input bitmap".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,7 @@ impl TxHashSet {
|
||||||
let output_pmmr: ReadonlyPMMR<'_, Output, _> =
|
let output_pmmr: ReadonlyPMMR<'_, Output, _> =
|
||||||
ReadonlyPMMR::at(&self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
|
ReadonlyPMMR::at(&self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
|
||||||
if let Some(out) = output_pmmr.get_data(pos) {
|
if let Some(out) = output_pmmr.get_data(pos) {
|
||||||
if OutputIdentifier::from(out) == *output_id {
|
if out == *output_id {
|
||||||
Ok(Some(CommitPos { pos, height }))
|
Ok(Some(CommitPos { pos, height }))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -1103,7 +1103,7 @@ impl<'a> Extension<'a> {
|
||||||
|
|
||||||
if head_header.height <= header.height {
|
if head_header.height <= header.height {
|
||||||
// Nothing to rewind but we do want to truncate the MMRs at header for consistency.
|
// Nothing to rewind but we do want to truncate the MMRs at header for consistency.
|
||||||
self.rewind_mmrs_to_pos(header.output_mmr_size, header.kernel_mmr_size, &vec![])?;
|
self.rewind_mmrs_to_pos(header.output_mmr_size, header.kernel_mmr_size, &[])?;
|
||||||
self.apply_to_bitmap_accumulator(&[header.output_mmr_size])?;
|
self.apply_to_bitmap_accumulator(&[header.output_mmr_size])?;
|
||||||
} else {
|
} else {
|
||||||
let mut affected_pos = vec![];
|
let mut affected_pos = vec![];
|
||||||
|
@ -1156,7 +1156,7 @@ impl<'a> Extension<'a> {
|
||||||
// Update our BitmapAccumulator based on affected outputs.
|
// Update our BitmapAccumulator based on affected outputs.
|
||||||
// We want to "unspend" every rewound spent output.
|
// We want to "unspend" every rewound spent output.
|
||||||
// Treat last_pos as an affected output to ensure we rebuild far enough back.
|
// Treat last_pos as an affected output to ensure we rebuild far enough back.
|
||||||
let mut affected_pos = spent_pos.clone();
|
let mut affected_pos = spent_pos;
|
||||||
affected_pos.push(self.output_pmmr.last_pos);
|
affected_pos.push(self.output_pmmr.last_pos);
|
||||||
|
|
||||||
// Remove any entries from the output_pos created by the block being rewound.
|
// Remove any entries from the output_pos created by the block being rewound.
|
||||||
|
@ -1181,7 +1181,7 @@ impl<'a> Extension<'a> {
|
||||||
// reused output commitment. For example an output at pos 1, spent, reused at pos 2.
|
// reused output commitment. For example an output at pos 1, spent, reused at pos 2.
|
||||||
// The output_pos index should be updated to reflect the old pos 1 when unspent.
|
// The output_pos index should be updated to reflect the old pos 1 when unspent.
|
||||||
if let Ok(spent) = spent {
|
if let Ok(spent) = spent {
|
||||||
for (x, y) in block.inputs().into_iter().zip(spent) {
|
for (x, y) in block.inputs().iter().zip(spent) {
|
||||||
batch.save_output_pos_height(&x.commitment(), y.pos, y.height)?;
|
batch.save_output_pos_height(&x.commitment(), y.pos, y.height)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1197,7 @@ impl<'a> Extension<'a> {
|
||||||
kernel_pos: u64,
|
kernel_pos: u64,
|
||||||
spent_pos: &[u64],
|
spent_pos: &[u64],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let bitmap: Bitmap = spent_pos.into_iter().map(|x| *x as u32).collect();
|
let bitmap: Bitmap = spent_pos.iter().map(|x| *x as u32).collect();
|
||||||
self.output_pmmr
|
self.output_pmmr
|
||||||
.rewind(output_pos, &bitmap)
|
.rewind(output_pos, &bitmap)
|
||||||
.map_err(&ErrorKind::TxHashSetErr)?;
|
.map_err(&ErrorKind::TxHashSetErr)?;
|
||||||
|
|
|
@ -188,10 +188,7 @@ impl SyncState {
|
||||||
|
|
||||||
/// Get sync error
|
/// Get sync error
|
||||||
pub fn sync_error(&self) -> Option<String> {
|
pub fn sync_error(&self) -> Option<String> {
|
||||||
self.sync_error
|
self.sync_error.read().as_ref().map(|e| e.to_string())
|
||||||
.read()
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|e| Some(e.to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear sync error
|
/// Clear sync error
|
||||||
|
|
|
@ -486,10 +486,10 @@ fn comments() -> HashMap<String, String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_key(line: &str) -> String {
|
fn get_key(line: &str) -> String {
|
||||||
if line.contains("[") && line.contains("]") {
|
if line.contains('[') && line.contains(']') {
|
||||||
return line.to_owned();
|
return line.to_owned();
|
||||||
} else if line.contains("=") {
|
} else if line.contains('=') {
|
||||||
return line.split("=").collect::<Vec<&str>>()[0].trim().to_owned();
|
return line.split('=').collect::<Vec<&str>>()[0].trim().to_owned();
|
||||||
} else {
|
} else {
|
||||||
return "NOT_FOUND".to_owned();
|
return "NOT_FOUND".to_owned();
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ fn get_key(line: &str) -> String {
|
||||||
|
|
||||||
pub fn insert_comments(orig: String) -> String {
|
pub fn insert_comments(orig: String) -> String {
|
||||||
let comments = comments();
|
let comments = comments();
|
||||||
let lines: Vec<&str> = orig.split("\n").collect();
|
let lines: Vec<&str> = orig.split('\n').collect();
|
||||||
let mut out_lines = vec![];
|
let mut out_lines = vec![];
|
||||||
for l in lines {
|
for l in lines {
|
||||||
let key = get_key(l);
|
let key = get_key(l);
|
||||||
|
@ -511,5 +511,5 @@ pub fn insert_comments(orig: String) -> String {
|
||||||
for l in out_lines {
|
for l in out_lines {
|
||||||
ret_val.push_str(&l);
|
ret_val.push_str(&l);
|
||||||
}
|
}
|
||||||
ret_val.to_owned()
|
ret_val
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,14 +34,14 @@ use crate::util::logger::LoggingConfig;
|
||||||
|
|
||||||
/// The default file name to use when trying to derive
|
/// The default file name to use when trying to derive
|
||||||
/// the node config file location
|
/// the node config file location
|
||||||
pub const SERVER_CONFIG_FILE_NAME: &'static str = "grin-server.toml";
|
pub const SERVER_CONFIG_FILE_NAME: &str = "grin-server.toml";
|
||||||
const SERVER_LOG_FILE_NAME: &'static str = "grin-server.log";
|
const SERVER_LOG_FILE_NAME: &str = "grin-server.log";
|
||||||
const GRIN_HOME: &'static str = ".grin";
|
const GRIN_HOME: &str = ".grin";
|
||||||
const GRIN_CHAIN_DIR: &'static str = "chain_data";
|
const GRIN_CHAIN_DIR: &str = "chain_data";
|
||||||
/// Node Rest API and V2 Owner API secret
|
/// Node Rest API and V2 Owner API secret
|
||||||
pub const API_SECRET_FILE_NAME: &'static str = ".api_secret";
|
pub const API_SECRET_FILE_NAME: &str = ".api_secret";
|
||||||
/// Foreign API secret
|
/// Foreign API secret
|
||||||
pub const FOREIGN_API_SECRET_FILE_NAME: &'static str = ".foreign_api_secret";
|
pub const FOREIGN_API_SECRET_FILE_NAME: &str = ".foreign_api_secret";
|
||||||
|
|
||||||
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {
|
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {
|
||||||
// Check if grin dir exists
|
// Check if grin dir exists
|
||||||
|
@ -103,7 +103,7 @@ fn check_api_secret_files(
|
||||||
secret_file_name: &str,
|
secret_file_name: &str,
|
||||||
) -> Result<(), ConfigError> {
|
) -> Result<(), ConfigError> {
|
||||||
let grin_path = get_grin_path(chain_type)?;
|
let grin_path = get_grin_path(chain_type)?;
|
||||||
let mut api_secret_path = grin_path.clone();
|
let mut api_secret_path = grin_path;
|
||||||
api_secret_path.push(secret_file_name);
|
api_secret_path.push(secret_file_name);
|
||||||
if !api_secret_path.exists() {
|
if !api_secret_path.exists() {
|
||||||
init_api_secret(&api_secret_path)
|
init_api_secret(&api_secret_path)
|
||||||
|
@ -236,15 +236,8 @@ impl GlobalConfig {
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(ConfigError::ParseError(
|
return Err(ConfigError::ParseError(
|
||||||
String::from(
|
self.config_file_path.unwrap().to_str().unwrap().to_string(),
|
||||||
self.config_file_path
|
format!("{}", e),
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.to_str()
|
|
||||||
.unwrap()
|
|
||||||
.clone(),
|
|
||||||
),
|
|
||||||
String::from(format!("{}", e)),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,10 +285,7 @@ impl GlobalConfig {
|
||||||
match encoded {
|
match encoded {
|
||||||
Ok(enc) => return Ok(enc),
|
Ok(enc) => return Ok(enc),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(ConfigError::SerializationError(String::from(format!(
|
return Err(ConfigError::SerializationError(format!("{}", e)));
|
||||||
"{}",
|
|
||||||
e
|
|
||||||
))));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl From<io::Error> for ConfigError {
|
||||||
fn from(error: io::Error) -> ConfigError {
|
fn from(error: io::Error) -> ConfigError {
|
||||||
ConfigError::FileIOError(
|
ConfigError::FileIOError(
|
||||||
String::from(""),
|
String::from(""),
|
||||||
String::from(format!("Error loading config file: {}", error)),
|
format!("Error loading config file: {}", error),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,8 +363,8 @@ impl BlockHeader {
|
||||||
proof: Proof,
|
proof: Proof,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
// Convert hex pre pow string
|
// Convert hex pre pow string
|
||||||
let mut header_bytes = from_hex(&pre_pow)
|
let mut header_bytes =
|
||||||
.map_err(|e| Error::Serialization(ser::Error::HexError(e.to_string())))?;
|
from_hex(&pre_pow).map_err(|e| Error::Serialization(ser::Error::HexError(e)))?;
|
||||||
// Serialize and append serialized nonce and proof
|
// Serialize and append serialized nonce and proof
|
||||||
serialize_default(&mut header_bytes, &nonce)?;
|
serialize_default(&mut header_bytes, &nonce)?;
|
||||||
serialize_default(&mut header_bytes, &proof)?;
|
serialize_default(&mut header_bytes, &proof)?;
|
||||||
|
|
|
@ -44,10 +44,9 @@ pub mod pubkey_serde {
|
||||||
let static_secp = static_secp_instance();
|
let static_secp = static_secp_instance();
|
||||||
let static_secp = static_secp.lock();
|
let static_secp = static_secp.lock();
|
||||||
String::deserialize(deserializer)
|
String::deserialize(deserializer)
|
||||||
.and_then(|string| from_hex(&string).map_err(|err| Error::custom(err.to_string())))
|
.and_then(|string| from_hex(&string).map_err(Error::custom))
|
||||||
.and_then(|bytes: Vec<u8>| {
|
.and_then(|bytes: Vec<u8>| {
|
||||||
PublicKey::from_slice(&static_secp, &bytes)
|
PublicKey::from_slice(&static_secp, &bytes).map_err(Error::custom)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,13 +81,13 @@ pub mod option_sig_serde {
|
||||||
let static_secp = static_secp.lock();
|
let static_secp = static_secp.lock();
|
||||||
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||||||
Some(string) => from_hex(&string)
|
Some(string) => from_hex(&string)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(Error::custom)
|
||||||
.and_then(|bytes: Vec<u8>| {
|
.and_then(|bytes: Vec<u8>| {
|
||||||
let mut b = [0u8; 64];
|
let mut b = [0u8; 64];
|
||||||
b.copy_from_slice(&bytes[0..64]);
|
b.copy_from_slice(&bytes[0..64]);
|
||||||
secp::Signature::from_compact(&static_secp, &b)
|
secp::Signature::from_compact(&static_secp, &b)
|
||||||
.map(Some)
|
.map(Some)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(Error::custom)
|
||||||
}),
|
}),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
})
|
})
|
||||||
|
@ -124,13 +123,13 @@ pub mod option_seckey_serde {
|
||||||
let static_secp = static_secp.lock();
|
let static_secp = static_secp.lock();
|
||||||
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||||||
Some(string) => from_hex(&string)
|
Some(string) => from_hex(&string)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(Error::custom)
|
||||||
.and_then(|bytes: Vec<u8>| {
|
.and_then(|bytes: Vec<u8>| {
|
||||||
let mut b = [0u8; 32];
|
let mut b = [0u8; 32];
|
||||||
b.copy_from_slice(&bytes[0..32]);
|
b.copy_from_slice(&bytes[0..32]);
|
||||||
secp::key::SecretKey::from_slice(&static_secp, &b)
|
secp::key::SecretKey::from_slice(&static_secp, &b)
|
||||||
.map(Some)
|
.map(Some)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(Error::custom)
|
||||||
}),
|
}),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
})
|
})
|
||||||
|
@ -161,12 +160,11 @@ pub mod sig_serde {
|
||||||
let static_secp = static_secp_instance();
|
let static_secp = static_secp_instance();
|
||||||
let static_secp = static_secp.lock();
|
let static_secp = static_secp.lock();
|
||||||
String::deserialize(deserializer)
|
String::deserialize(deserializer)
|
||||||
.and_then(|string| from_hex(&string).map_err(|err| Error::custom(err.to_string())))
|
.and_then(|string| from_hex(&string).map_err(Error::custom))
|
||||||
.and_then(|bytes: Vec<u8>| {
|
.and_then(|bytes: Vec<u8>| {
|
||||||
let mut b = [0u8; 64];
|
let mut b = [0u8; 64];
|
||||||
b.copy_from_slice(&bytes[0..64]);
|
b.copy_from_slice(&bytes[0..64]);
|
||||||
secp::Signature::from_compact(&static_secp, &b)
|
secp::Signature::from_compact(&static_secp, &b).map_err(Error::custom)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +194,7 @@ pub mod option_commitment_serde {
|
||||||
{
|
{
|
||||||
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||||||
Some(string) => from_hex(&string)
|
Some(string) => from_hex(&string)
|
||||||
.map_err(|err| Error::custom(err.to_string()))
|
.map_err(Error::custom)
|
||||||
.and_then(|bytes: Vec<u8>| Ok(Some(Commitment::from_vec(bytes.to_vec())))),
|
.and_then(|bytes: Vec<u8>| Ok(Some(Commitment::from_vec(bytes.to_vec())))),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
})
|
})
|
||||||
|
@ -208,9 +206,8 @@ where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
String::deserialize(deserializer).and_then(|string| {
|
String::deserialize(deserializer)
|
||||||
BlindingFactor::from_hex(&string).map_err(|err| Error::custom(err.to_string()))
|
.and_then(|string| BlindingFactor::from_hex(&string).map_err(Error::custom))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a RangeProof from a hex string
|
/// Creates a RangeProof from a hex string
|
||||||
|
@ -221,7 +218,7 @@ where
|
||||||
use serde::de::{Error, IntoDeserializer};
|
use serde::de::{Error, IntoDeserializer};
|
||||||
|
|
||||||
let val = String::deserialize(deserializer)
|
let val = String::deserialize(deserializer)
|
||||||
.and_then(|string| from_hex(&string).map_err(|err| Error::custom(err.to_string())))?;
|
.and_then(|string| from_hex(&string).map_err(Error::custom))?;
|
||||||
RangeProof::deserialize(val.into_deserializer())
|
RangeProof::deserialize(val.into_deserializer())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +229,7 @@ where
|
||||||
{
|
{
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
String::deserialize(deserializer)
|
String::deserialize(deserializer)
|
||||||
.and_then(|string| from_hex(&string).map_err(|err| Error::custom(err.to_string())))
|
.and_then(|string| from_hex(&string).map_err(Error::custom))
|
||||||
.and_then(|bytes: Vec<u8>| Ok(Commitment::from_vec(bytes.to_vec())))
|
.and_then(|bytes: Vec<u8>| Ok(Commitment::from_vec(bytes.to_vec())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,9 +387,9 @@ mod test {
|
||||||
SerTest {
|
SerTest {
|
||||||
opt_skey: Some(sk.clone()),
|
opt_skey: Some(sk.clone()),
|
||||||
pub_key: PublicKey::from_secret_key(&secp, &sk).unwrap(),
|
pub_key: PublicKey::from_secret_key(&secp, &sk).unwrap(),
|
||||||
opt_sig: Some(sig.clone()),
|
opt_sig: Some(sig),
|
||||||
opt_commit: Some(commit),
|
opt_commit: Some(commit),
|
||||||
sig: sig.clone(),
|
sig: sig,
|
||||||
num: 30,
|
num: 30,
|
||||||
opt_num: Some(33),
|
opt_num: Some(33),
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,8 +183,8 @@ impl<'de> Visitor<'de> for PeerAddrs {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let socket_addrs = entry
|
let socket_addrs = entry
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.expect(format!("Unable to resolve DNS: {}", entry).as_str());
|
.unwrap_or_else(|_| panic!("Unable to resolve DNS: {}", entry));
|
||||||
peers.append(&mut socket_addrs.map(|addr| PeerAddr(addr)).collect());
|
peers.append(&mut socket_addrs.map(PeerAddr).collect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
);
|
);
|
||||||
|
|
||||||
// If we have missing kernels then we know we cannot hydrate this compact block.
|
// If we have missing kernels then we know we cannot hydrate this compact block.
|
||||||
if missing_short_ids.len() > 0 {
|
if !missing_short_ids.is_empty() {
|
||||||
self.request_block(&cb.header, peer_info, chain::Options::NONE);
|
self.request_block(&cb.header, peer_info, chain::Options::NONE);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
@ -224,15 +224,13 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
{
|
{
|
||||||
debug!("successfully hydrated block from tx pool!");
|
debug!("successfully hydrated block from tx pool!");
|
||||||
self.process_block(block, peer_info, chain::Options::NONE)
|
self.process_block(block, peer_info, chain::Options::NONE)
|
||||||
|
} else if self.sync_state.status() == SyncStatus::NoSync {
|
||||||
|
debug!("adapter: block invalid after hydration, requesting full block");
|
||||||
|
self.request_block(&cb.header, peer_info, chain::Options::NONE);
|
||||||
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
if self.sync_state.status() == SyncStatus::NoSync {
|
debug!("block invalid after hydration, ignoring it, cause still syncing");
|
||||||
debug!("adapter: block invalid after hydration, requesting full block");
|
Ok(true)
|
||||||
self.request_block(&cb.header, peer_info, chain::Options::NONE);
|
|
||||||
Ok(true)
|
|
||||||
} else {
|
|
||||||
debug!("block invalid after hydration, ignoring it, cause still syncing");
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("failed to retrieve previous block header (still syncing?)");
|
debug!("failed to retrieve previous block header (still syncing?)");
|
||||||
|
@ -294,7 +292,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
peer_info.addr
|
peer_info.addr
|
||||||
);
|
);
|
||||||
|
|
||||||
if bhs.len() == 0 {
|
if bhs.is_empty() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +302,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Block headers refused by chain: {:?}", e);
|
debug!("Block headers refused by chain: {:?}", e);
|
||||||
if e.is_bad_data() {
|
if e.is_bad_data() {
|
||||||
return Ok(false);
|
Ok(false)
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
|
@ -361,8 +359,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kernel_data_write(&self, reader: &mut dyn Read) -> Result<bool, chain::Error> {
|
fn kernel_data_write(&self, reader: &mut dyn Read) -> Result<bool, chain::Error> {
|
||||||
let res = self.chain().kernel_data_write(reader)?;
|
self.chain().kernel_data_write(reader)?;
|
||||||
error!("***** kernel_data_write: {:?}", res);
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +620,7 @@ impl NetToChainAdapter {
|
||||||
// uses a different thread to avoid blocking the caller thread (likely a peer)
|
// uses a different thread to avoid blocking the caller thread (likely a peer)
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
if 0 == rng.gen_range(0, global::COMPACTION_CHECK) {
|
if 0 == rng.gen_range(0, global::COMPACTION_CHECK) {
|
||||||
let chain = self.chain().clone();
|
let chain = self.chain();
|
||||||
let _ = thread::Builder::new()
|
let _ = thread::Builder::new()
|
||||||
.name("compactor".to_string())
|
.name("compactor".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
|
@ -904,25 +901,25 @@ impl pool::BlockChain for PoolToChainAdapter {
|
||||||
fn chain_head(&self) -> Result<BlockHeader, pool::PoolError> {
|
fn chain_head(&self) -> Result<BlockHeader, pool::PoolError> {
|
||||||
self.chain()
|
self.chain()
|
||||||
.head_header()
|
.head_header()
|
||||||
.map_err(|_| pool::PoolError::Other(format!("failed to get head_header")))
|
.map_err(|_| pool::PoolError::Other("failed to get head_header".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_block_header(&self, hash: &Hash) -> Result<BlockHeader, pool::PoolError> {
|
fn get_block_header(&self, hash: &Hash) -> Result<BlockHeader, pool::PoolError> {
|
||||||
self.chain()
|
self.chain()
|
||||||
.get_block_header(hash)
|
.get_block_header(hash)
|
||||||
.map_err(|_| pool::PoolError::Other(format!("failed to get block_header")))
|
.map_err(|_| pool::PoolError::Other("failed to get block_header".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_block_sums(&self, hash: &Hash) -> Result<BlockSums, pool::PoolError> {
|
fn get_block_sums(&self, hash: &Hash) -> Result<BlockSums, pool::PoolError> {
|
||||||
self.chain()
|
self.chain()
|
||||||
.get_block_sums(hash)
|
.get_block_sums(hash)
|
||||||
.map_err(|_| pool::PoolError::Other(format!("failed to get block_sums")))
|
.map_err(|_| pool::PoolError::Other("failed to get block_sums".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_tx(&self, tx: &Transaction) -> Result<(), pool::PoolError> {
|
fn validate_tx(&self, tx: &Transaction) -> Result<(), pool::PoolError> {
|
||||||
self.chain()
|
self.chain()
|
||||||
.validate_tx(tx)
|
.validate_tx(tx)
|
||||||
.map_err(|_| pool::PoolError::Other(format!("failed to validate tx")))
|
.map_err(|_| pool::PoolError::Other("failed to validate tx".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_coinbase_maturity(&self, tx: &Transaction) -> Result<(), pool::PoolError> {
|
fn verify_coinbase_maturity(&self, tx: &Transaction) -> Result<(), pool::PoolError> {
|
||||||
|
|
|
@ -223,13 +223,13 @@ impl PeerStats {
|
||||||
/// Convert from a peer directly
|
/// Convert from a peer directly
|
||||||
pub fn from_peer(peer: &p2p::Peer) -> PeerStats {
|
pub fn from_peer(peer: &p2p::Peer) -> PeerStats {
|
||||||
// State
|
// State
|
||||||
let mut state = "Disconnected";
|
let state = if peer.is_banned() {
|
||||||
if peer.is_connected() {
|
"Banned"
|
||||||
state = "Connected";
|
} else if peer.is_connected() {
|
||||||
}
|
"Connected"
|
||||||
if peer.is_banned() {
|
} else {
|
||||||
state = "Banned";
|
"Disconnected"
|
||||||
}
|
};
|
||||||
let addr = peer.info.addr.to_string();
|
let addr = peer.info.addr.to_string();
|
||||||
let direction = match peer.info.direction {
|
let direction = match peer.info.direction {
|
||||||
p2p::types::Direction::Inbound => "Inbound",
|
p2p::types::Direction::Inbound => "Inbound",
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub fn monitor_transactions(
|
||||||
let run_interval = Duration::from_secs(10);
|
let run_interval = Duration::from_secs(10);
|
||||||
let mut last_run = Instant::now()
|
let mut last_run = Instant::now()
|
||||||
.checked_sub(Duration::from_secs(20))
|
.checked_sub(Duration::from_secs(20))
|
||||||
.unwrap_or_else(|| Instant::now());
|
.unwrap_or_else(Instant::now);
|
||||||
loop {
|
loop {
|
||||||
// Halt Dandelion monitor if we have been notified that we are stopping.
|
// Halt Dandelion monitor if we have been notified that we are stopping.
|
||||||
if stop_state.is_stopped() {
|
if stop_state.is_stopped() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ use crate::p2p::ChainAdapter;
|
||||||
use crate::util::StopState;
|
use crate::util::StopState;
|
||||||
|
|
||||||
// DNS Seeds with contact email associated
|
// DNS Seeds with contact email associated
|
||||||
const MAINNET_DNS_SEEDS: &'static [&'static str] = &[
|
const MAINNET_DNS_SEEDS: &[&str] = &[
|
||||||
"mainnet.seed.grin.icu", // gary.peverell@protonmail.com
|
"mainnet.seed.grin.icu", // gary.peverell@protonmail.com
|
||||||
"mainnet.seed.713.mw", // jasper@713.mw
|
"mainnet.seed.713.mw", // jasper@713.mw
|
||||||
"mainnet.seed.grin.lesceller.com", // q.lesceller@gmail.com
|
"mainnet.seed.grin.lesceller.com", // q.lesceller@gmail.com
|
||||||
|
@ -41,7 +41,7 @@ const MAINNET_DNS_SEEDS: &'static [&'static str] = &[
|
||||||
"grinseed.yeastplume.org", // yeastplume@protonmail.com
|
"grinseed.yeastplume.org", // yeastplume@protonmail.com
|
||||||
"mainnet-seed.grinnode.live", // info@grinnode.live
|
"mainnet-seed.grinnode.live", // info@grinnode.live
|
||||||
];
|
];
|
||||||
const FLOONET_DNS_SEEDS: &'static [&'static str] = &[
|
const FLOONET_DNS_SEEDS: &[&str] = &[
|
||||||
"floonet.seed.grin.icu", // gary.peverell@protonmail.com
|
"floonet.seed.grin.icu", // gary.peverell@protonmail.com
|
||||||
"floonet.seed.713.mw", // jasper@713.mw
|
"floonet.seed.713.mw", // jasper@713.mw
|
||||||
"floonet.seed.grin.lesceller.com", // q.lesceller@gmail.com
|
"floonet.seed.grin.lesceller.com", // q.lesceller@gmail.com
|
||||||
|
@ -124,8 +124,8 @@ pub fn connect_and_monitor(
|
||||||
if Utc::now() - prev_ping > Duration::seconds(10) {
|
if Utc::now() - prev_ping > Duration::seconds(10) {
|
||||||
let total_diff = peers.total_difficulty();
|
let total_diff = peers.total_difficulty();
|
||||||
let total_height = peers.total_height();
|
let total_height = peers.total_height();
|
||||||
if total_diff.is_ok() && total_height.is_ok() {
|
if let (Ok(total_diff), Ok(total_height)) = (total_diff, total_height) {
|
||||||
peers.check_all(total_diff.unwrap(), total_height.unwrap());
|
peers.check_all(total_diff, total_height);
|
||||||
prev_ping = Utc::now();
|
prev_ping = Utc::now();
|
||||||
} else {
|
} else {
|
||||||
error!("failed to get peers difficulty and/or height");
|
error!("failed to get peers difficulty and/or height");
|
||||||
|
@ -224,7 +224,7 @@ fn monitor_peers(
|
||||||
|
|
||||||
// take a random defunct peer and mark it healthy: over a long period any
|
// take a random defunct peer and mark it healthy: over a long period any
|
||||||
// peer will see another as defunct eventually, gives us a chance to retry
|
// peer will see another as defunct eventually, gives us a chance to retry
|
||||||
if defuncts.len() > 0 {
|
if !defuncts.is_empty() {
|
||||||
defuncts.shuffle(&mut thread_rng());
|
defuncts.shuffle(&mut thread_rng());
|
||||||
let _ = peers.update_state(defuncts[0].addr, p2p::State::Healthy);
|
let _ = peers.update_state(defuncts[0].addr, p2p::State::Healthy);
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ fn connect_to_seeds_and_preferred_peers(
|
||||||
None => trace!("No preferred peers"),
|
None => trace!("No preferred peers"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if peer_addrs.len() == 0 {
|
if peer_addrs.is_empty() {
|
||||||
warn!("No seeds were retrieved.");
|
warn!("No seeds were retrieved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,10 +322,8 @@ fn listen_for_addrs(
|
||||||
last_connect_time.format("%H:%M:%S%.3f").to_string(),
|
last_connect_time.format("%H:%M:%S%.3f").to_string(),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else if let Some(history) = connecting_history.get_mut(&addr) {
|
||||||
if let Some(history) = connecting_history.get_mut(&addr) {
|
*history = now;
|
||||||
*history = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connecting_history.insert(addr, now);
|
connecting_history.insert(addr, now);
|
||||||
|
@ -354,7 +352,7 @@ fn listen_for_addrs(
|
||||||
let old: Vec<_> = connecting_history
|
let old: Vec<_> = connecting_history
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&(_, t)| *t + Duration::seconds(connect_min_interval) < now)
|
.filter(|&(_, t)| *t + Duration::seconds(connect_min_interval) < now)
|
||||||
.map(|(s, _)| s.clone())
|
.map(|(s, _)| *s)
|
||||||
.collect();
|
.collect();
|
||||||
for addr in old {
|
for addr in old {
|
||||||
connecting_history.remove(&addr);
|
connecting_history.remove(&addr);
|
||||||
|
@ -392,7 +390,7 @@ fn resolve_dns_to_addrs(dns_records: &Vec<String>) -> Vec<PeerAddr> {
|
||||||
match dns.to_socket_addrs() {
|
match dns.to_socket_addrs() {
|
||||||
Ok(addrs) => addresses.append(
|
Ok(addrs) => addresses.append(
|
||||||
&mut addrs
|
&mut addrs
|
||||||
.map(|addr| PeerAddr(addr))
|
.map(PeerAddr)
|
||||||
.filter(|addr| !addresses.contains(addr))
|
.filter(|addr| !addresses.contains(addr))
|
||||||
.collect(),
|
.collect(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl Server {
|
||||||
let mut stratum_stats = serv.state_info.stratum_stats.write();
|
let mut stratum_stats = serv.state_info.stratum_stats.write();
|
||||||
stratum_stats.is_enabled = true;
|
stratum_stats.is_enabled = true;
|
||||||
}
|
}
|
||||||
serv.start_stratum_server(c.clone());
|
serv.start_stratum_server(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ impl Server {
|
||||||
// This uses fs2 and should be safe cross-platform unless somebody abuses the file itself.
|
// This uses fs2 and should be safe cross-platform unless somebody abuses the file itself.
|
||||||
fn one_grin_at_a_time(config: &ServerConfig) -> Result<Arc<File>, Error> {
|
fn one_grin_at_a_time(config: &ServerConfig) -> Result<Arc<File>, Error> {
|
||||||
let path = Path::new(&config.db_root);
|
let path = Path::new(&config.db_root);
|
||||||
fs::create_dir_all(path.clone())?;
|
fs::create_dir_all(&path)?;
|
||||||
let path = path.join("grin.lock");
|
let path = path.join("grin.lock");
|
||||||
let lock_file = fs::OpenOptions::new()
|
let lock_file = fs::OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
|
@ -283,7 +283,7 @@ impl Server {
|
||||||
let key = match config.tls_certificate_key.clone() {
|
let key = match config.tls_certificate_key.clone() {
|
||||||
Some(k) => k,
|
Some(k) => k,
|
||||||
None => {
|
None => {
|
||||||
let msg = format!("Private key for certificate is not set");
|
let msg = "Private key for certificate is not set".to_string();
|
||||||
return Err(Error::ArgumentError(msg));
|
return Err(Error::ArgumentError(msg));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -298,16 +298,16 @@ impl Server {
|
||||||
tx_pool.clone(),
|
tx_pool.clone(),
|
||||||
p2p_server.peers.clone(),
|
p2p_server.peers.clone(),
|
||||||
sync_state.clone(),
|
sync_state.clone(),
|
||||||
api_secret.clone(),
|
api_secret,
|
||||||
foreign_api_secret.clone(),
|
foreign_api_secret,
|
||||||
tls_conf.clone(),
|
tls_conf,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
info!("Starting dandelion monitor: {}", &config.api_http_addr);
|
info!("Starting dandelion monitor: {}", &config.api_http_addr);
|
||||||
let dandelion_thread = dandelion_monitor::monitor_transactions(
|
let dandelion_thread = dandelion_monitor::monitor_transactions(
|
||||||
config.dandelion_config.clone(),
|
config.dandelion_config.clone(),
|
||||||
tx_pool.clone(),
|
tx_pool.clone(),
|
||||||
pool_net_adapter.clone(),
|
pool_net_adapter,
|
||||||
verifier_cache.clone(),
|
verifier_cache.clone(),
|
||||||
stop_state.clone(),
|
stop_state.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -357,7 +357,7 @@ impl Server {
|
||||||
let sync_state = self.sync_state.clone();
|
let sync_state = self.sync_state.clone();
|
||||||
|
|
||||||
let mut stratum_server = stratumserver::StratumServer::new(
|
let mut stratum_server = stratumserver::StratumServer::new(
|
||||||
config.clone(),
|
config,
|
||||||
self.chain.clone(),
|
self.chain.clone(),
|
||||||
self.tx_pool.clone(),
|
self.tx_pool.clone(),
|
||||||
self.verifier_cache.clone(),
|
self.verifier_cache.clone(),
|
||||||
|
@ -395,7 +395,7 @@ impl Server {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut miner = Miner::new(
|
let mut miner = Miner::new(
|
||||||
config.clone(),
|
config,
|
||||||
self.chain.clone(),
|
self.chain.clone(),
|
||||||
self.tx_pool.clone(),
|
self.tx_pool.clone(),
|
||||||
self.verifier_cache.clone(),
|
self.verifier_cache.clone(),
|
||||||
|
@ -520,7 +520,7 @@ impl Server {
|
||||||
.filter(|metadata| metadata.is_file())
|
.filter(|metadata| metadata.is_file())
|
||||||
.fold(0, |acc, m| acc + m.len());
|
.fold(0, |acc, m| acc + m.len());
|
||||||
|
|
||||||
let disk_usage_gb = format!("{:.*}", 3, (disk_usage_bytes as f64 / 1_000_000_000 as f64));
|
let disk_usage_gb = format!("{:.*}", 3, (disk_usage_bytes as f64 / 1_000_000_000_f64));
|
||||||
|
|
||||||
Ok(ServerStats {
|
Ok(ServerStats {
|
||||||
peer_count: self.peer_count(),
|
peer_count: self.peer_count(),
|
||||||
|
|
|
@ -104,12 +104,12 @@ impl BodySync {
|
||||||
.filter(|x| {
|
.filter(|x| {
|
||||||
// only ask for blocks that we have not yet processed
|
// only ask for blocks that we have not yet processed
|
||||||
// either successfully stored or in our orphan list
|
// either successfully stored or in our orphan list
|
||||||
!self.chain.get_block(x).is_ok() && !self.chain.is_orphan(x)
|
self.chain.get_block(x).is_err() && !self.chain.is_orphan(x)
|
||||||
})
|
})
|
||||||
.take(block_count)
|
.take(block_count)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if hashes_to_get.len() > 0 {
|
if !hashes_to_get.is_empty() {
|
||||||
let body_head = self.chain.head()?;
|
let body_head = self.chain.head()?;
|
||||||
let header_head = self.chain.header_head()?;
|
let header_head = self.chain.header_head()?;
|
||||||
|
|
||||||
|
|
|
@ -136,31 +136,29 @@ impl HeaderSync {
|
||||||
if all_headers_received {
|
if all_headers_received {
|
||||||
// reset the stalling start time if syncing goes well
|
// reset the stalling start time if syncing goes well
|
||||||
self.stalling_ts = None;
|
self.stalling_ts = None;
|
||||||
} else {
|
} else if let Some(ref stalling_ts) = self.stalling_ts {
|
||||||
if let Some(ref stalling_ts) = self.stalling_ts {
|
if let Some(ref peer) = self.syncing_peer {
|
||||||
if let Some(ref peer) = self.syncing_peer {
|
match self.sync_state.status() {
|
||||||
match self.sync_state.status() {
|
SyncStatus::HeaderSync { .. } | SyncStatus::BodySync { .. } => {
|
||||||
SyncStatus::HeaderSync { .. } | SyncStatus::BodySync { .. } => {
|
// Ban this fraud peer which claims a higher work but can't send us the real headers
|
||||||
// Ban this fraud peer which claims a higher work but can't send us the real headers
|
if now > *stalling_ts + Duration::seconds(120)
|
||||||
if now > *stalling_ts + Duration::seconds(120)
|
&& header_head.total_difficulty < peer.info.total_difficulty()
|
||||||
&& header_head.total_difficulty < peer.info.total_difficulty()
|
{
|
||||||
|
if let Err(e) = self
|
||||||
|
.peers
|
||||||
|
.ban_peer(peer.info.addr, ReasonForBan::FraudHeight)
|
||||||
{
|
{
|
||||||
if let Err(e) = self
|
error!("failed to ban peer {}: {:?}", peer.info.addr, e);
|
||||||
.peers
|
}
|
||||||
.ban_peer(peer.info.addr, ReasonForBan::FraudHeight)
|
info!(
|
||||||
{
|
|
||||||
error!("failed to ban peer {}: {:?}", peer.info.addr, e);
|
|
||||||
}
|
|
||||||
info!(
|
|
||||||
"sync: ban a fraud peer: {}, claimed height: {}, total difficulty: {}",
|
"sync: ban a fraud peer: {}, claimed height: {}, total difficulty: {}",
|
||||||
peer.info.addr,
|
peer.info.addr,
|
||||||
peer.info.height(),
|
peer.info.height(),
|
||||||
peer.info.total_difficulty(),
|
peer.info.total_difficulty(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +196,7 @@ impl HeaderSync {
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = peer.send_header_request(locator);
|
let _ = peer.send_header_request(locator);
|
||||||
return Some(peer.clone());
|
return Some(peer);
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +210,7 @@ impl HeaderSync {
|
||||||
|
|
||||||
// for security, clear history_locator[] in any case of header chain rollback,
|
// for security, clear history_locator[] in any case of header chain rollback,
|
||||||
// the easiest way is to check whether the sync head and the header head are identical.
|
// the easiest way is to check whether the sync head and the header head are identical.
|
||||||
if self.history_locator.len() > 0 && tip.hash() != self.chain.header_head()?.hash() {
|
if !self.history_locator.is_empty() && tip.hash() != self.chain.header_head()?.hash() {
|
||||||
self.history_locator.retain(|&x| x.0 == 0);
|
self.history_locator.retain(|&x| x.0 == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +222,7 @@ impl HeaderSync {
|
||||||
locator.push(l);
|
locator.push(l);
|
||||||
} else {
|
} else {
|
||||||
// start at last known hash and go backward
|
// start at last known hash and go backward
|
||||||
let last_loc = locator.last().unwrap().clone();
|
let last_loc = locator.last().unwrap();
|
||||||
let mut header_cursor = self.chain.get_block_header(&last_loc.1);
|
let mut header_cursor = self.chain.get_block_header(&last_loc.1);
|
||||||
while let Ok(header) = header_cursor {
|
while let Ok(header) = header_cursor {
|
||||||
if header.height == h {
|
if header.height == h {
|
||||||
|
@ -246,13 +244,13 @@ impl HeaderSync {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether we have a value close enough to the provided height in the locator
|
// Whether we have a value close enough to the provided height in the locator
|
||||||
fn close_enough(locator: &Vec<(u64, Hash)>, height: u64) -> Option<(u64, Hash)> {
|
fn close_enough(locator: &[(u64, Hash)], height: u64) -> Option<(u64, Hash)> {
|
||||||
if locator.len() == 0 {
|
if locator.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// bounds, lower that last is last
|
// bounds, lower that last is last
|
||||||
if locator.last().unwrap().0 >= height {
|
if locator.last().unwrap().0 >= height {
|
||||||
return locator.last().map(|l| l.clone());
|
return locator.last().copied();
|
||||||
}
|
}
|
||||||
// higher than first is first if within an acceptable gap
|
// higher than first is first if within an acceptable gap
|
||||||
if locator[0].0 < height && height.saturating_sub(127) < locator[0].0 {
|
if locator[0].0 < height && height.saturating_sub(127) < locator[0].0 {
|
||||||
|
@ -261,9 +259,9 @@ fn close_enough(locator: &Vec<(u64, Hash)>, height: u64) -> Option<(u64, Hash)>
|
||||||
for hh in locator.windows(2) {
|
for hh in locator.windows(2) {
|
||||||
if height <= hh[0].0 && height > hh[1].0 {
|
if height <= hh[0].0 && height > hh[1].0 {
|
||||||
if hh[0].0 - height < height - hh[1].0 {
|
if hh[0].0 - height < height - hh[1].0 {
|
||||||
return Some(hh[0].clone());
|
return Some(hh[0]);
|
||||||
} else {
|
} else {
|
||||||
return Some(hh[1].clone());
|
return Some(hh[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ impl StateSync {
|
||||||
error!("state_sync: send_txhashset_request err! {:?}", e);
|
error!("state_sync: send_txhashset_request err! {:?}", e);
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
return Ok(peer.clone());
|
return Ok(peer);
|
||||||
}
|
}
|
||||||
Err(p2p::Error::PeerException)
|
Err(p2p::Error::PeerException)
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ impl SyncRunner {
|
||||||
};
|
};
|
||||||
|
|
||||||
let peer_diff = peer_info.total_difficulty();
|
let peer_diff = peer_info.total_difficulty();
|
||||||
if peer_diff > local_diff.clone() + threshold.clone() {
|
if peer_diff > local_diff + threshold {
|
||||||
info!(
|
info!(
|
||||||
"sync: total_difficulty {}, peer_difficulty {}, threshold {} (last 5 blocks), enabling sync",
|
"sync: total_difficulty {}, peer_difficulty {}, threshold {} (last 5 blocks), enabling sync",
|
||||||
local_diff,
|
local_diff,
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl Handler {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Handler {
|
Handler {
|
||||||
id: id,
|
id: id,
|
||||||
workers: Arc::new(WorkersList::new(stratum_stats.clone())),
|
workers: Arc::new(WorkersList::new(stratum_stats)),
|
||||||
sync_state: sync_state,
|
sync_state: sync_state,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
current_state: Arc::new(RwLock::new(State::new(minimum_share_difficulty))),
|
current_state: Arc::new(RwLock::new(State::new(minimum_share_difficulty))),
|
||||||
|
@ -450,7 +450,7 @@ impl Handler {
|
||||||
} else {
|
} else {
|
||||||
// Do some validation but dont submit
|
// Do some validation but dont submit
|
||||||
let res = pow::verify_size(&b.header);
|
let res = pow::verify_size(&b.header);
|
||||||
if !res.is_ok() {
|
if res.is_err() {
|
||||||
// Return error status
|
// Return error status
|
||||||
error!(
|
error!(
|
||||||
"(Server ID: {}) Failed to validate share at height {}, hash {}, edge_bits {}, nonce {}, job_id {}. {:?}",
|
"(Server ID: {}) Failed to validate share at height {}, hash {}, edge_bits {}, nonce {}, job_id {}. {:?}",
|
||||||
|
@ -471,7 +471,7 @@ impl Handler {
|
||||||
let worker = self.workers.get_worker(worker_id)?;
|
let worker = self.workers.get_worker(worker_id)?;
|
||||||
let submitted_by = match worker.login {
|
let submitted_by = match worker.login {
|
||||||
None => worker.id.to_string(),
|
None => worker.id.to_string(),
|
||||||
Some(login) => login.clone(),
|
Some(login) => login,
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
@ -488,12 +488,11 @@ impl Handler {
|
||||||
);
|
);
|
||||||
self.workers
|
self.workers
|
||||||
.update_stats(worker_id, |worker_stats| worker_stats.num_accepted += 1);
|
.update_stats(worker_id, |worker_stats| worker_stats.num_accepted += 1);
|
||||||
let submit_response;
|
let submit_response = if share_is_block {
|
||||||
if share_is_block {
|
format!("blockfound - {}", b.hash().to_hex())
|
||||||
submit_response = format!("blockfound - {}", b.hash().to_hex());
|
|
||||||
} else {
|
} else {
|
||||||
submit_response = "ok".to_string();
|
"ok".to_string()
|
||||||
}
|
};
|
||||||
return Ok((
|
return Ok((
|
||||||
serde_json::to_value(submit_response).unwrap(),
|
serde_json::to_value(submit_response).unwrap(),
|
||||||
share_is_block,
|
share_is_block,
|
||||||
|
@ -518,7 +517,7 @@ impl Handler {
|
||||||
"(Server ID: {}) sending block {} with id {} to stratum clients",
|
"(Server ID: {}) sending block {} with id {} to stratum clients",
|
||||||
self.id, job_template.height, job_template.job_id,
|
self.id, job_template.height, job_template.job_id,
|
||||||
);
|
);
|
||||||
self.workers.broadcast(job_request_json.clone());
|
self.workers.broadcast(job_request_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(
|
||||||
|
@ -546,10 +545,11 @@ impl Handler {
|
||||||
{
|
{
|
||||||
debug!("resend updated block");
|
debug!("resend updated block");
|
||||||
let mut state = self.current_state.write();
|
let mut state = self.current_state.write();
|
||||||
let mut wallet_listener_url: Option<String> = None;
|
let wallet_listener_url = if !config.burn_reward {
|
||||||
if !config.burn_reward {
|
Some(config.wallet_listener_url.clone())
|
||||||
wallet_listener_url = Some(config.wallet_listener_url.clone());
|
} else {
|
||||||
}
|
None
|
||||||
|
};
|
||||||
// If this is a new block, clear the current_block version history
|
// If this is a new block, clear the current_block version history
|
||||||
let clear_blocks = current_hash != latest_hash;
|
let clear_blocks = current_hash != latest_hash;
|
||||||
|
|
||||||
|
@ -599,10 +599,9 @@ impl Handler {
|
||||||
fn accept_connections(listen_addr: SocketAddr, handler: Arc<Handler>) {
|
fn accept_connections(listen_addr: SocketAddr, handler: Arc<Handler>) {
|
||||||
info!("Start tokio stratum server");
|
info!("Start tokio stratum server");
|
||||||
let task = async move {
|
let task = async move {
|
||||||
let mut listener = TcpListener::bind(&listen_addr).await.expect(&format!(
|
let mut listener = TcpListener::bind(&listen_addr).await.unwrap_or_else(|_| {
|
||||||
"Stratum: Failed to bind to listen address {}",
|
panic!("Stratum: Failed to bind to listen address {}", listen_addr)
|
||||||
listen_addr
|
});
|
||||||
));
|
|
||||||
let server = listener
|
let server = listener
|
||||||
.incoming()
|
.incoming()
|
||||||
.filter_map(|s| async { s.map_err(|e| error!("accept error = {:?}", e)).ok() })
|
.filter_map(|s| async { s.map_err(|e| error!("accept error = {:?}", e)).ok() })
|
||||||
|
@ -726,7 +725,9 @@ impl WorkersList {
|
||||||
|
|
||||||
pub fn login(&self, worker_id: usize, login: String, agent: String) -> Result<(), RpcError> {
|
pub fn login(&self, worker_id: usize, login: String, agent: String) -> Result<(), RpcError> {
|
||||||
let mut wl = self.workers_list.write();
|
let mut wl = self.workers_list.write();
|
||||||
let mut worker = wl.get_mut(&worker_id).ok_or(RpcError::internal_error())?;
|
let mut worker = wl
|
||||||
|
.get_mut(&worker_id)
|
||||||
|
.ok_or_else(RpcError::internal_error)?;
|
||||||
worker.login = Some(login);
|
worker.login = Some(login);
|
||||||
// XXX TODO Future - Validate password?
|
// XXX TODO Future - Validate password?
|
||||||
worker.agent = agent;
|
worker.agent = agent;
|
||||||
|
@ -750,7 +751,7 @@ impl WorkersList {
|
||||||
.read()
|
.read()
|
||||||
.worker_stats
|
.worker_stats
|
||||||
.get(worker_id)
|
.get(worker_id)
|
||||||
.ok_or(RpcError::internal_error())
|
.ok_or_else(RpcError::internal_error)
|
||||||
.map(|ws| ws.clone())
|
.map(|ws| ws.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,7 +886,7 @@ where
|
||||||
{
|
{
|
||||||
params
|
params
|
||||||
.and_then(|v| serde_json::from_value(v).ok())
|
.and_then(|v| serde_json::from_value(v).ok())
|
||||||
.ok_or(RpcError::invalid_request())
|
.ok_or_else(RpcError::invalid_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub fn client_command(client_args: &ArgMatches<'_>, global_config: GlobalConfig)
|
||||||
|
|
||||||
pub fn show_status(config: &ServerConfig, api_secret: Option<String>) {
|
pub fn show_status(config: &ServerConfig, api_secret: Option<String>) {
|
||||||
println!();
|
println!();
|
||||||
let title = format!("Grin Server Status");
|
let title = "Grin Server Status".to_string();
|
||||||
if term::stdout().is_none() {
|
if term::stdout().is_none() {
|
||||||
println!("Could not open terminal");
|
println!("Could not open terminal");
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +100,7 @@ pub fn ban_peer(config: &ServerConfig, peer_addr: &SocketAddr, api_secret: Optio
|
||||||
config.api_http_addr,
|
config.api_http_addr,
|
||||||
peer_addr.to_string()
|
peer_addr.to_string()
|
||||||
);
|
);
|
||||||
match api::client::post_no_ret(url.as_str(), api_secret, ¶ms).map_err(|e| Error::API(e)) {
|
match api::client::post_no_ret(url.as_str(), api_secret, ¶ms).map_err(Error::API) {
|
||||||
Ok(_) => writeln!(e, "Successfully banned peer {}", peer_addr.to_string()).unwrap(),
|
Ok(_) => writeln!(e, "Successfully banned peer {}", peer_addr.to_string()).unwrap(),
|
||||||
Err(_) => writeln!(e, "Failed to ban peer {}", peer_addr).unwrap(),
|
Err(_) => writeln!(e, "Failed to ban peer {}", peer_addr).unwrap(),
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,7 @@ pub fn unban_peer(config: &ServerConfig, peer_addr: &SocketAddr, api_secret: Opt
|
||||||
let res: Result<(), api::Error>;
|
let res: Result<(), api::Error>;
|
||||||
res = api::client::post_no_ret(url.as_str(), api_secret, ¶ms);
|
res = api::client::post_no_ret(url.as_str(), api_secret, ¶ms);
|
||||||
|
|
||||||
match res.map_err(|e| Error::API(e)) {
|
match res.map_err(Error::API) {
|
||||||
Ok(_) => writeln!(e, "Successfully unbanned peer {}", peer_addr).unwrap(),
|
Ok(_) => writeln!(e, "Successfully unbanned peer {}", peer_addr).unwrap(),
|
||||||
Err(_) => writeln!(e, "Failed to unban peer {}", peer_addr).unwrap(),
|
Err(_) => writeln!(e, "Failed to unban peer {}", peer_addr).unwrap(),
|
||||||
};
|
};
|
||||||
|
@ -132,10 +132,9 @@ pub fn list_connected_peers(config: &ServerConfig, api_secret: Option<String>) {
|
||||||
|
|
||||||
let peers_info = api::client::get::<Vec<p2p::types::PeerInfoDisplay>>(url.as_str(), api_secret);
|
let peers_info = api::client::get::<Vec<p2p::types::PeerInfoDisplay>>(url.as_str(), api_secret);
|
||||||
|
|
||||||
match peers_info.map_err(|e| Error::API(e)) {
|
match peers_info.map_err(Error::API) {
|
||||||
Ok(connected_peers) => {
|
Ok(connected_peers) => {
|
||||||
let mut index = 0;
|
for (index, connected_peer) in connected_peers.into_iter().enumerate() {
|
||||||
for connected_peer in connected_peers {
|
|
||||||
writeln!(e, "Peer {}:", index).unwrap();
|
writeln!(e, "Peer {}:", index).unwrap();
|
||||||
writeln!(e, "Capabilities: {:?}", connected_peer.capabilities).unwrap();
|
writeln!(e, "Capabilities: {:?}", connected_peer.capabilities).unwrap();
|
||||||
writeln!(e, "User agent: {}", connected_peer.user_agent).unwrap();
|
writeln!(e, "User agent: {}", connected_peer.user_agent).unwrap();
|
||||||
|
@ -145,7 +144,6 @@ pub fn list_connected_peers(config: &ServerConfig, api_secret: Option<String>) {
|
||||||
writeln!(e, "Total difficulty: {}", connected_peer.total_difficulty).unwrap();
|
writeln!(e, "Total difficulty: {}", connected_peer.total_difficulty).unwrap();
|
||||||
writeln!(e, "Direction: {:?}", connected_peer.direction).unwrap();
|
writeln!(e, "Direction: {:?}", connected_peer.direction).unwrap();
|
||||||
println!();
|
println!();
|
||||||
index = index + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => writeln!(e, "Failed to get connected peers").unwrap(),
|
Err(_) => writeln!(e, "Failed to get connected peers").unwrap(),
|
||||||
|
@ -159,7 +157,7 @@ fn get_status_from_node(
|
||||||
api_secret: Option<String>,
|
api_secret: Option<String>,
|
||||||
) -> Result<api::Status, Error> {
|
) -> Result<api::Status, Error> {
|
||||||
let url = format!("http://{}/v1/status", config.api_http_addr);
|
let url = format!("http://{}/v1/status", config.api_http_addr);
|
||||||
api::client::get::<api::Status>(url.as_str(), api_secret).map_err(|e| Error::API(e))
|
api::client::get::<api::Status>(url.as_str(), api_secret).map_err(Error::API)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error type wrapping underlying module errors.
|
/// Error type wrapping underlying module errors.
|
||||||
|
|
|
@ -121,10 +121,7 @@ pub fn server_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(seeds) = a.values_of("seed") {
|
if let Some(seeds) = a.values_of("seed") {
|
||||||
let peers = seeds
|
let peers = seeds.filter_map(|s| s.parse().ok()).map(PeerAddr).collect();
|
||||||
.filter_map(|s| s.parse().ok())
|
|
||||||
.map(|sa| PeerAddr(sa))
|
|
||||||
.collect();
|
|
||||||
server_config.p2p_config.seeding_type = Seeding::List;
|
server_config.p2p_config.seeding_type = Seeding::List;
|
||||||
server_config.p2p_config.seeds = Some(PeerAddrs { peers });
|
server_config.p2p_config.seeds = Some(PeerAddrs { peers });
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,14 +49,12 @@ pub fn info_strings() -> (String, String) {
|
||||||
built_info::GIT_VERSION.map_or_else(|| "".to_owned(), |v| format!(" (git {})", v)),
|
built_info::GIT_VERSION.map_or_else(|| "".to_owned(), |v| format!(" (git {})", v)),
|
||||||
built_info::TARGET,
|
built_info::TARGET,
|
||||||
built_info::RUSTC_VERSION,
|
built_info::RUSTC_VERSION,
|
||||||
)
|
),
|
||||||
.to_string(),
|
|
||||||
format!(
|
format!(
|
||||||
"Built with profile \"{}\", features \"{}\".",
|
"Built with profile \"{}\", features \"{}\".",
|
||||||
built_info::PROFILE,
|
built_info::PROFILE,
|
||||||
built_info::FEATURES_STR,
|
built_info::FEATURES_STR,
|
||||||
)
|
),
|
||||||
.to_string(),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,17 +77,12 @@ fn real_main() -> i32 {
|
||||||
let node_config;
|
let node_config;
|
||||||
|
|
||||||
// Temporary wallet warning message
|
// Temporary wallet warning message
|
||||||
match args.subcommand() {
|
if let ("wallet", _) = args.subcommand() {
|
||||||
("wallet", _) => {
|
println!();
|
||||||
println!();
|
println!("As of v1.1.0, the wallet has been split into a separate executable.");
|
||||||
println!("As of v1.1.0, the wallet has been split into a separate executable.");
|
println!("Please visit https://github.com/mimblewimble/grin-wallet/releases to download");
|
||||||
println!(
|
println!();
|
||||||
"Please visit https://github.com/mimblewimble/grin-wallet/releases to download"
|
return 0;
|
||||||
);
|
|
||||||
println!();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let chain_type = if args.is_present("floonet") {
|
let chain_type = if args.is_present("floonet") {
|
||||||
|
@ -101,15 +94,12 @@ fn real_main() -> i32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Deal with configuration file creation
|
// Deal with configuration file creation
|
||||||
match args.subcommand() {
|
if let ("server", Some(server_args)) = args.subcommand() {
|
||||||
("server", Some(server_args)) => {
|
// If it's just a server config command, do it and exit
|
||||||
// If it's just a server config command, do it and exit
|
if let ("config", Some(_)) = server_args.subcommand() {
|
||||||
if let ("config", Some(_)) = server_args.subcommand() {
|
cmd::config_command_server(&chain_type, SERVER_CONFIG_FILE_NAME);
|
||||||
cmd::config_command_server(&chain_type, SERVER_CONFIG_FILE_NAME);
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load relevant config
|
// Load relevant config
|
||||||
|
@ -150,7 +140,7 @@ fn real_main() -> i32 {
|
||||||
};
|
};
|
||||||
init_logger(Some(logging_config), logs_tx);
|
init_logger(Some(logging_config), logs_tx);
|
||||||
|
|
||||||
global::set_mining_mode(config.members.unwrap().server.clone().chain_type);
|
global::set_mining_mode(config.members.unwrap().server.chain_type);
|
||||||
|
|
||||||
if let Some(file_path) = &config.config_file_path {
|
if let Some(file_path) = &config.config_file_path {
|
||||||
info!(
|
info!(
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
use cursive::align::HAlign;
|
use cursive::align::HAlign;
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::event::{EventResult, Key};
|
use cursive::event::Key;
|
||||||
use cursive::view::Identifiable;
|
use cursive::view::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{
|
use cursive::views::{
|
||||||
|
@ -63,12 +63,10 @@ pub fn create() -> Box<dyn View> {
|
||||||
.on_pre_event('j', move |c| {
|
.on_pre_event('j', move |c| {
|
||||||
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
||||||
s.select_down(1)(c);
|
s.select_down(1)(c);
|
||||||
Some(EventResult::Consumed(None));
|
|
||||||
})
|
})
|
||||||
.on_pre_event('k', move |c| {
|
.on_pre_event('k', move |c| {
|
||||||
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
||||||
s.select_up(1)(c);
|
s.select_up(1)(c);
|
||||||
Some(EventResult::Consumed(None));
|
|
||||||
})
|
})
|
||||||
.on_pre_event(Key::Tab, move |c| {
|
.on_pre_event(Key::Tab, move |c| {
|
||||||
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
let mut s: ViewRef<SelectView<&str>> = c.find_name(MAIN_MENU).unwrap();
|
||||||
|
@ -77,7 +75,6 @@ pub fn create() -> Box<dyn View> {
|
||||||
} else {
|
} else {
|
||||||
s.select_down(1)(c);
|
s.select_down(1)(c);
|
||||||
}
|
}
|
||||||
Some(EventResult::Consumed(None));
|
|
||||||
});
|
});
|
||||||
let main_menu = LinearLayout::new(Orientation::Vertical)
|
let main_menu = LinearLayout::new(Orientation::Vertical)
|
||||||
.child(ResizedView::with_full_height(main_menu))
|
.child(ResizedView::with_full_height(main_menu))
|
||||||
|
|
|
@ -142,8 +142,8 @@ impl TableViewItem<DiffColumn> for DiffBlock {
|
||||||
DiffColumn::PoWType => pow_type,
|
DiffColumn::PoWType => pow_type,
|
||||||
DiffColumn::Difficulty => self.difficulty.to_string(),
|
DiffColumn::Difficulty => self.difficulty.to_string(),
|
||||||
DiffColumn::SecondaryScaling => self.secondary_scaling.to_string(),
|
DiffColumn::SecondaryScaling => self.secondary_scaling.to_string(),
|
||||||
DiffColumn::Time => format!("{}", datetime).to_string(),
|
DiffColumn::Time => format!("{}", datetime),
|
||||||
DiffColumn::Duration => format!("{}s", self.duration).to_string(),
|
DiffColumn::Duration => format!("{}s", self.duration),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ impl TUIStatusListener for TUIMiningView {
|
||||||
});
|
});
|
||||||
let dur = time::Duration::from_secs(stats.diff_stats.average_block_time);
|
let dur = time::Duration::from_secs(stats.diff_stats.average_block_time);
|
||||||
c.call_on_name("diff_avg_block_time", |t: &mut TextView| {
|
c.call_on_name("diff_avg_block_time", |t: &mut TextView| {
|
||||||
t.set_content(format!("{} Secs", dur.as_secs()).to_string());
|
t.set_content(format!("{} Secs", dur.as_secs()));
|
||||||
});
|
});
|
||||||
c.call_on_name("diff_avg_difficulty", |t: &mut TextView| {
|
c.call_on_name("diff_avg_difficulty", |t: &mut TextView| {
|
||||||
t.set_content(stats.diff_stats.average_difficulty.to_string());
|
t.set_content(stats.diff_stats.average_difficulty.to_string());
|
||||||
|
|
|
@ -61,7 +61,8 @@ impl TableViewItem<PeerColumn> for PeerStats {
|
||||||
fn to_column(&self, column: PeerColumn) -> String {
|
fn to_column(&self, column: PeerColumn) -> String {
|
||||||
// Converts optional size to human readable size
|
// Converts optional size to human readable size
|
||||||
fn size_to_string(size: u64) -> String {
|
fn size_to_string(size: u64) -> String {
|
||||||
size.file_size(CONVENTIONAL).unwrap_or("-".to_string())
|
size.file_size(CONVENTIONAL)
|
||||||
|
.unwrap_or_else(|_| "-".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
match column {
|
match column {
|
||||||
|
@ -71,15 +72,13 @@ impl TableViewItem<PeerColumn> for PeerStats {
|
||||||
"↑: {}, ↓: {}",
|
"↑: {}, ↓: {}",
|
||||||
size_to_string(self.sent_bytes_per_sec),
|
size_to_string(self.sent_bytes_per_sec),
|
||||||
size_to_string(self.received_bytes_per_sec),
|
size_to_string(self.received_bytes_per_sec),
|
||||||
)
|
),
|
||||||
.to_string(),
|
|
||||||
PeerColumn::TotalDifficulty => format!(
|
PeerColumn::TotalDifficulty => format!(
|
||||||
"{} D @ {} H ({}s)",
|
"{} D @ {} H ({}s)",
|
||||||
self.total_difficulty,
|
self.total_difficulty,
|
||||||
self.height,
|
self.height,
|
||||||
(Utc::now() - self.last_seen).num_seconds(),
|
(Utc::now() - self.last_seen).num_seconds(),
|
||||||
)
|
),
|
||||||
.to_string(),
|
|
||||||
PeerColumn::Direction => self.direction.clone(),
|
PeerColumn::Direction => self.direction.clone(),
|
||||||
PeerColumn::Version => format!("{}", self.version),
|
PeerColumn::Version => format!("{}", self.version),
|
||||||
PeerColumn::UserAgent => self.user_agent.clone(),
|
PeerColumn::UserAgent => self.user_agent.clone(),
|
||||||
|
@ -175,8 +174,7 @@ impl TUIStatusListener for TUIPeerView {
|
||||||
l.height,
|
l.height,
|
||||||
stats.chain_stats.total_difficulty,
|
stats.chain_stats.total_difficulty,
|
||||||
stats.chain_stats.height
|
stats.chain_stats.height
|
||||||
)
|
),
|
||||||
.to_string(),
|
|
||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
};
|
};
|
||||||
let _ = c.call_on_name(
|
let _ = c.call_on_name(
|
||||||
|
|
|
@ -625,8 +625,9 @@ impl<T: TableViewItem<H> + PartialEq, H: Eq + Hash + Copy + Clone + 'static> Tab
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.rows_to_items = rows_to_items;
|
self.rows_to_items = rows_to_items;
|
||||||
|
if let Some(o) = old_item {
|
||||||
old_item.map(|o| self.set_selected_item(o));
|
self.set_selected_item(o)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ impl Controller {
|
||||||
let stat_update_interval = 1;
|
let stat_update_interval = 1;
|
||||||
let mut next_stat_update = Utc::now().timestamp() + stat_update_interval;
|
let mut next_stat_update = Utc::now().timestamp() + stat_update_interval;
|
||||||
while self.ui.step() {
|
while self.ui.step() {
|
||||||
while let Some(message) = self.rx.try_iter().next() {
|
if let Some(message) = self.rx.try_iter().next() {
|
||||||
match message {
|
match message {
|
||||||
ControllerMessage::Shutdown => {
|
ControllerMessage::Shutdown => {
|
||||||
warn!("Shutdown in progress, please wait");
|
warn!("Shutdown in progress, please wait");
|
||||||
|
|
Loading…
Reference in a new issue