diff --git a/Cargo.toml b/Cargo.toml index 1812d39..5d2fa08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ edition = "2018" build = "build.rs" name = "ton_block" -version = "1.7.24" +version = "1.7.26" [target.'cfg(target_arch = "wasm32")'.dependencies] clear_on_drop = { version = "0.2", features = ["no_cc"] } diff --git a/src/accounts.rs b/src/accounts.rs index 112c840..5e81d29 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -460,6 +460,7 @@ impl fmt::Display for AccountStorage { /// account_something_new$001 = AccountState; /// +#[allow(clippy::enum_variant_names)] #[derive(Clone, Debug, Eq, PartialEq)] enum AccountState { AccountUninit, @@ -1026,7 +1027,9 @@ impl Account { } /// setting due payment pub fn set_due_payment(&mut self, due_payment: Option) { - self.stuff_mut().map(|s| s.storage_stat.due_payment = due_payment); + if let Some(stuff) = self.stuff_mut() { + stuff.storage_stat.due_payment = due_payment + } } /// getting balance of the account @@ -1039,7 +1042,9 @@ impl Account { /// setting balance of the account pub fn set_balance(&mut self, balance: CurrencyCollection) { - self.stuff_mut().map(|s| s.storage.balance = balance); + if let Some(stuff) = self.stuff_mut() { + stuff.storage.balance = balance + } } /// adding funds to account (for example, for credit phase transaction) diff --git a/src/bintree.rs b/src/bintree.rs index 564d06c..aa34d10 100644 --- a/src/bintree.rs +++ b/src/bintree.rs @@ -39,7 +39,7 @@ pub trait BinTreeType { } } if key.is_empty() { - X::construct_from(&mut cursor).map(|x| Some(x)) + Ok(Some(X::construct_from(&mut cursor)?)) } else { Ok(None) } @@ -103,7 +103,7 @@ where F: FnOnce(X, X) -> Result, X: Default + Serializable + Deserializable fn internal_split(data: &SliceData, mut key: SliceData, splitter: F) -> Result> where F: FnOnce(X) -> Result<(X, X)>, X: Default + Serializable + Deserializable { - if data.remaining_bits() == 1 && data.get_bits(0, 1)? == 1 { // bt_fork$1 {X:Type} left:^(BinTree X) right:^(BinTree X) + if data.remaining_bits() == 1 && data.get_bit(0)? { // bt_fork$1 {X:Type} left:^(BinTree X) right:^(BinTree X) if data.remaining_references() < 2 { return Ok(None) } @@ -139,7 +139,7 @@ where F: FnOnce(X) -> Result<(X, X)>, X: Default + Serializable + Deserializable fn internal_update(data: &SliceData, mut key: SliceData, mutator: F) -> Result> where F: FnOnce(X) -> Result, X: Default + Serializable + Deserializable { - if data.remaining_bits() == 1 && data.get_bits(0, 1)? == 1 { // bt_fork$1 {X:Type} left:^(BinTree X) right:^(BinTree X) + if data.remaining_bits() == 1 && data.get_bit(0)? { // bt_fork$1 {X:Type} left:^(BinTree X) right:^(BinTree X) if data.remaining_references() < 2 { return Ok(None) } @@ -203,16 +203,16 @@ where let left = X::construct_from(cursor)?; match sibling { Some(cell) => { - let mut cursor = SliceData::from(cell.clone()); + let mut cursor = SliceData::from(cell); if cursor.get_next_bit()? { - func(key.clone(), left, None)? + func(key, left, None)? } else if check_sibling { func(key, left, Some(X::construct_from(&mut cursor)?))? } else { true } } - None => func(key.clone(), left, None)? + None => func(key, left, None)? } }; Ok(result) @@ -362,7 +362,7 @@ impl BinTreeAug= 1 && len <= 8) { + if !(1..=8).contains(&len) { fail!( BlockError::InvalidData( "Failed check: `len >= 1 && len <= 8`".to_string() @@ -1271,7 +1271,7 @@ impl Deserializable for TopBlockDescr { if slice.remaining_references() == 0 { fail!(BlockError::TvmException(ExceptionCode::CellUnderflow)) } - self.chain.push(slice.checked_drain_reference()?.clone()); + self.chain.push(slice.checked_drain_reference()?); if i != 0 { if slice.remaining_references() == 0 { fail!(BlockError::TvmException(ExceptionCode::CellUnderflow)) @@ -1296,14 +1296,14 @@ pub struct TopBlockDescrSet { impl TopBlockDescrSet { pub fn get_top_block_descr(&self, shard: &ShardIdent) -> Result> { match self.collection.0.get(shard.full_key_with_tag()?)? { - Some(slice) => TopBlockDescr::construct_from_cell(slice.reference(0)?).map(|r| Some(r)), + Some(slice) => TopBlockDescr::construct_from_cell(slice.reference(0)?).map(Some), None => Ok(None) } } pub fn insert(&mut self, shard: &ShardIdent, descr: &TopBlockDescr) -> Result<()> { let key = shard.full_key_with_tag()?; let value = descr.serialize()?; - self.collection.0.setref(key, &value.into()).map(|_|()) + self.collection.0.setref(key, &value).map(|_|()) } pub fn is_empty(&self) -> bool { self.collection.is_empty() diff --git a/src/config_params.rs b/src/config_params.rs index ccaa67b..265bbd6 100644 --- a/src/config_params.rs +++ b/src/config_params.rs @@ -205,6 +205,12 @@ impl ConfigParams { _ => fail!("no elector params in config") } } + pub fn validators_count(&self) -> Result { + match self.config(16)? { + Some(ConfigParamEnum::ConfigParam16(param)) => Ok(param), + _ => fail!("no elector params in config") + } + } // TODO 16 validators count // TODO 17 stakes config pub fn storage_prices(&self) -> Result { @@ -317,6 +323,7 @@ pub enum GlobalCapabilities { CapMbppEnabled = 64, CapFastStorageStat = 128, CapInitCodeHash = 256, + CapOffHypercube = 512, } impl ConfigParams { @@ -2709,13 +2716,13 @@ impl ConfigParam39 { pub fn get(&self, key: &UInt256) -> Result { self .validator_keys - .get(key) - .and_then(|vtk| vtk.ok_or_else(|| error!(BlockError::InvalidArg(key.to_hex_string())))) + .get(key)? + .ok_or_else(|| error!(BlockError::InvalidArg(format!("{:x}", key)))) } /// insert value pub fn insert(&mut self, key: &UInt256, validator_key: &ValidatorSignedTempKey) -> Result<()> { - self.validator_keys.set(key, &validator_key) + self.validator_keys.set(key, validator_key) } } diff --git a/src/envelope_message.rs b/src/envelope_message.rs index 2c06a08..8b89e95 100644 --- a/src/envelope_message.rs +++ b/src/envelope_message.rs @@ -519,13 +519,13 @@ impl MsgEnvelope { /// is message route in one workchain pub fn same_workchain(&self) -> Result { let msg = self.read_message()?; - debug_assert!(msg.is_internal(), "Message with hash {} is not internal", - self.message_cell().repr_hash().to_hex_string()); + debug_assert!(msg.is_internal(), "Message with hash {:x} is not internal", + self.message_cell().repr_hash()); if let (Some(src), Some(dst)) = (msg.src_ref(), msg.dst_ref()) { return Ok(src.get_workchain_id() == dst.get_workchain_id()) } - fail!("Message with hash {} has wrong type of src/dst address", - self.message_cell().repr_hash().to_hex_string()) + fail!("Message with hash {:x} has wrong type of src/dst address", + self.message_cell().repr_hash()) } } diff --git a/src/hashmapaug.rs b/src/hashmapaug.rs index 6e46803..6c24682 100644 --- a/src/hashmapaug.rs +++ b/src/hashmapaug.rs @@ -19,6 +19,7 @@ use ton_types::{ error, fail, Result, IBitstring, BuilderData, Cell, SliceData, ExceptionCode, HashmapType, Leaf, HashmapFilterResult, HashmapRemover, }; +use std::cmp::Ordering; /// trait for types used as Augment to calc aug on forks pub trait Augmentable: Clone + Default + Serializable + Deserializable { @@ -70,29 +71,16 @@ macro_rules! define_HashmapAugE { /// Constructs new HashmapAugE for bit_len keys pub fn new() -> Self { Self { - extra: Default::default(), + extra: <$y_type>::default(), bit_len: $bit_len, data: None, } } - /// Deserialization from SliceData - just clone and set window - pub fn with_data(slice: &mut SliceData) -> Result { - let data = match slice.get_next_bit()? { - true => Some(slice.checked_drain_reference()?), - false => None - }; - let extra = <$y_type>::construct_from(slice)?; - Ok(Self { - extra, - bit_len: $bit_len, - data - }) - } /// Constructs from cell, extracts total aug pub fn with_hashmap(data: Option) -> Result { let extra = match data { Some(ref root) => Self::find_extra(&mut root.into(), $bit_len)?, - None => Default::default() + None => <$y_type>::default() }; Ok(Self { extra, @@ -208,7 +196,7 @@ macro_rules! define_HashmapAugE { impl Default for $varname { fn default() -> Self { Self { - extra: Default::default(), + extra: <$y_type>::default(), bit_len: $bit_len, data: None } @@ -229,9 +217,17 @@ macro_rules! define_HashmapAugE { } impl Deserializable for $varname { - fn read_from(&mut self, slice: &mut SliceData) -> Result<()>{ - *self = $varname::with_data(slice)?; - Ok(()) + fn construct_from(slice: &mut SliceData) -> Result{ + let data = match slice.get_next_bit()? { + true => Some(slice.checked_drain_reference()?), + false => None + }; + let extra = <$y_type>::construct_from(slice)?; + Ok(Self { + extra, + bit_len: $bit_len, + data + }) } } @@ -252,7 +248,7 @@ pub trait HashmapAugType Result<&Y> { let aug = match self.data() { Some(root) => Self::find_extra(&mut SliceData::from(root), self.bit_len())?, - None => Default::default() + None => Y::default(), }; self.set_root_extra(aug); Ok(self.root_extra()) @@ -698,39 +694,38 @@ pub trait HashmapAugType Result> { let label = cursor.get_label(bit_len)?; let label_length = label.remaining_bits(); - if label_length < bit_len { - bit_len -= label_length + 1; + match label_length.cmp(&bit_len) { + Ordering::Less => { + bit_len -= label_length + 1; - let mut aug = cursor.clone(); - aug.checked_drain_reference()?; - aug.checked_drain_reference()?; - key.checked_append_references_and_data(&label)?; - let to_visit = match callback(key.data(), key.length_in_bits(), aug)? { - TraverseNextStep::Stop => return Ok(None), - TraverseNextStep::End(r) => return Ok(Some(r)), - TraverseNextStep::VisitZero => [Some(0), None], - TraverseNextStep::VisitOne => [Some(1), None], - TraverseNextStep::VisitZeroOne => [Some(0), Some(1)], - TraverseNextStep::VisitOneZero => [Some(1), Some(0)], - }; - for i in to_visit.iter() { - if let Some(i) = i { + let mut aug = cursor.clone(); + aug.checked_drain_reference()?; + aug.checked_drain_reference()?; + key.checked_append_references_and_data(&label)?; + let to_visit = match callback(key.data(), key.length_in_bits(), aug)? { + TraverseNextStep::Stop => return Ok(None), + TraverseNextStep::End(r) => return Ok(Some(r)), + TraverseNextStep::VisitZero => [Some(0), None], + TraverseNextStep::VisitOne => [Some(1), None], + TraverseNextStep::VisitZeroOne => [Some(0), Some(1)], + TraverseNextStep::VisitOneZero => [Some(1), Some(0)], + }; + for i in to_visit.iter().flatten() { let mut key = key.clone(); key.append_bit_bool(*i != 0)?; - let ref mut child = SliceData::from(cursor.reference(*i)?); + let child = &mut SliceData::from(cursor.reference(*i)?); if let Some(r) = Self::traverse_internal(child, key, bit_len, callback)? { return Ok(Some(r)) } } } - } else if label_length == bit_len { - key.checked_append_references_and_data(&label)?; - return match callback(key.data(), key.length_in_bits(), cursor.clone())? { - TraverseNextStep::End(r) => Ok(Some(r)), - _ => Ok(None), + Ordering::Equal => { + key.checked_append_references_and_data(&label)?; + if let TraverseNextStep::End(r) = callback(key.data(), key.length_in_bits(), cursor.clone())? { + return Ok(Some(r)) + } } - } else { - fail!(BlockError::InvalidData("label_length > bit_len".to_string())) + _ => fail!(BlockError::InvalidData("label_length > bit_len".to_string())) } Ok(None) } diff --git a/src/inbound_messages.rs b/src/inbound_messages.rs index 9bbbc5f..e2965dc 100644 --- a/src/inbound_messages.rs +++ b/src/inbound_messages.rs @@ -246,13 +246,13 @@ impl InMsg { pub fn message_cell(&self) -> Result { Ok( match self { - InMsg::External(ref x) => x.message_cell().clone(), - InMsg::IHR(ref x) => x.message_cell().clone(), - InMsg::Immediatelly(ref x) => x.read_message()?.message_cell().clone(), - InMsg::Final(ref x) => x.read_message()?.message_cell().clone(), - InMsg::Transit(ref x) => x.read_in_message()?.message_cell().clone(), - InMsg::DiscardedFinal(ref x) => x.read_message()?.message_cell().clone(), - InMsg::DiscardedTransit(ref x) => x.read_message()?.message_cell().clone(), + InMsg::External(ref x) => x.message_cell(), + InMsg::IHR(ref x) => x.message_cell(), + InMsg::Immediatelly(ref x) => x.read_message()?.message_cell(), + InMsg::Final(ref x) => x.read_message()?.message_cell(), + InMsg::Transit(ref x) => x.read_in_message()?.message_cell(), + InMsg::DiscardedFinal(ref x) => x.read_message()?.message_cell(), + InMsg::DiscardedTransit(ref x) => x.read_message()?.message_cell(), InMsg::None => Default::default() } ) @@ -544,7 +544,7 @@ impl Deserializable for InMsgIHR { self.msg.read_from_reference(cell)?; self.transaction.read_from_reference(cell)?; self.ihr_fee.read_from(cell)?; - self.proof_created = cell.checked_drain_reference()?.clone(); + self.proof_created = cell.checked_drain_reference()?; Ok(()) } } @@ -730,7 +730,7 @@ impl InMsgDiscardedTransit { Ok( InMsgDiscardedTransit { in_msg: ChildCell::with_struct(msg)?, - transaction_id: transaction_id, + transaction_id, fwd_fee: fee, proof_delivered: proof } @@ -773,7 +773,7 @@ impl Deserializable for InMsgDiscardedTransit { self.in_msg.read_from_reference(cell)?; self.transaction_id.read_from(cell)?; self.fwd_fee.read_from(cell)?; - self.proof_delivered = cell.checked_drain_reference()?.clone(); + self.proof_delivered = cell.checked_drain_reference()?; Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 5e96549..5755d7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,6 +165,12 @@ pub trait Deserializable: Default { x.read_from(slice)?; Ok(x) } + fn construct_maybe_from(slice: &mut SliceData) -> Result> { + match slice.get_next_bit()? { + true => Ok(Some(Self::construct_from(slice)?)), + false => Ok(None) + } + } fn construct_from_cell(cell: Cell) -> Result { Self::construct_from(&mut cell.into()) } @@ -209,7 +215,7 @@ pub trait MaybeSerialize { impl Deserializable for Cell { fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { - *self = cell.checked_drain_reference()?.clone(); + *self = cell.checked_drain_reference()?; Ok(()) } } @@ -296,7 +302,7 @@ impl Serializable for AccountId { if self.remaining_bits() != 256 { fail!("account_id must contain 256 bits, but {}", self.remaining_bits()) } - cell.append_bytestring(&self)?; + cell.append_bytestring(self)?; Ok(()) } } @@ -306,7 +312,7 @@ impl Deserializable for () { if cell.remaining_bits() == 0 && cell.remaining_references() == 0 { Ok(()) } else { - fail!("It must be True by TLB, but some data is present: {}", cell.to_hex_string()) + fail!("It must be True by TLB, but some data is present: {:x}", cell) } } } diff --git a/src/master.rs b/src/master.rs index 1bb5575..677072c 100644 --- a/src/master.rs +++ b/src/master.rs @@ -58,6 +58,7 @@ pub struct ShardIdentFull { } impl ShardIdentFull { + // #[deprecated(note = "use Display converter in format!")] pub fn to_hex_string(&self) -> String { format!("{}:{:016X}", self.workchain_id, self.prefix) } @@ -185,7 +186,7 @@ impl ShardHashes { new_shards.insert(r, vec![block_id]); } else if descr.before_merge { let p = shard.merge()?; - new_shards.entry(p).or_insert_with(|| vec![]).push(block_id) + new_shards.entry(p).or_insert_with(Vec::new).push(block_id) } else { new_shards.insert(shard, vec![block_id]); } @@ -215,7 +216,7 @@ impl ShardHashes { fail!("get_shard_cc_seqno: invalid shard2 {} for {}", &shard2.shard, shard) } - return Ok(std::cmp::max(shard1.descr.next_catchain_seqno, shard2.descr.next_catchain_seqno) + 1) + Ok(std::cmp::max(shard1.descr.next_catchain_seqno, shard2.descr.next_catchain_seqno) + 1) } pub fn split_shard( &mut self, @@ -268,13 +269,13 @@ impl ShardHashes { fail!("Workchain {} is already added", workchain_id); } - let mut descr = ShardDescr::default(); - descr.reg_mc_seqno = reg_mc_seqno; - descr.root_hash = zerostate_root_hash; - descr.file_hash = zerostate_file_hash; - descr.min_ref_mc_seqno = !0; - descr.next_validator_shard = SHARD_FULL; - descr.min_ref_mc_seqno = 0; + let descr = ShardDescr { + reg_mc_seqno, + root_hash: zerostate_root_hash, + file_hash: zerostate_file_hash, + next_validator_shard: SHARD_FULL, + ..ShardDescr::default() + }; let tree = BinTree::with_item(&descr)?; self.set(&workchain_id, &InRefValue(tree)) @@ -288,7 +289,7 @@ impl ShardHashes { self.iterate_with_keys(|workchain_id: i32, InRefValue(bintree)| { println!("workchain: {}", workchain_id); bintree.iterate(|prefix, descr| { - let shard = ShardIdent::with_prefix_slice(workchain_id, prefix.clone().into())?; + let shard = ShardIdent::with_prefix_slice(workchain_id, prefix)?; println!( "shard: {:064b} seq_no: {} shard: 0x{}", shard.shard_prefix_with_tag(), @@ -312,7 +313,7 @@ pub struct McShardRecord { impl McShardRecord { pub fn from_shard_descr(shard: ShardIdent, descr: ShardDescr) -> Self { - let block_id = BlockIdExt::with_params(shard, descr.seq_no, descr.root_hash.clone(), descr.file_hash.clone()); + let block_id = BlockIdExt::with_params(shard.clone(), descr.seq_no, descr.root_hash.clone(), descr.file_hash.clone()); Self { shard, descr, block_id } } @@ -340,8 +341,8 @@ impl McShardRecord { min_ref_mc_seqno: info.min_ref_mc_seqno(), gen_utime: info.gen_utime().0, split_merge_at: FutureSplitMerge::None, // is not used in McShardRecord - fees_collected: value_flow.fees_collected.clone(), - funds_created: value_flow.created.clone(), + fees_collected: value_flow.fees_collected, + funds_created: value_flow.created, }, block_id, } @@ -496,7 +497,7 @@ impl Deserializable for McBlockExtra { self.shards.read_from(cell)?; self.fees.read_from(cell)?; - let ref mut cell1 = cell.checked_drain_reference()?.into(); + let cell1 = &mut cell.checked_drain_reference()?.into(); self.prev_blk_signatures.read_from(cell1)?; self.recover_create_msg = if cell1.get_next_bit()? { @@ -651,14 +652,17 @@ impl OldMcBlocksInfo { } } let y = req_seqno >> (d - 1); - if y < 2 * x { - // (x << d) > req_seqno <=> x > (req_seqno >> d) = (y >> 1) <=> 2 * x > y - return Ok(TraverseNextStep::Stop); // all nodes in subtree have block.seqno > req_seqno => skip - } - return if y == 2 * x { - Ok(TraverseNextStep::VisitZero) // visit only left ("0") - } else { - Ok(TraverseNextStep::VisitOneZero) // visit right, then left ("1" then "0") + match y.cmp(&(2 * x)) { + std::cmp::Ordering::Less => { + // (x << d) > req_seqno <=> x > (req_seqno >> d) = (y >> 1) <=> 2 * x > y + Ok(TraverseNextStep::Stop) // all nodes in subtree have block.seqno > req_seqno => skip + } + std::cmp::Ordering::Equal => { + Ok(TraverseNextStep::VisitZero) // visit only left ("0") + } + _ => { + Ok(TraverseNextStep::VisitOneZero) // visit right, then left ("1" then "0") + } } })?; @@ -692,14 +696,17 @@ impl OldMcBlocksInfo { } } let y = req_seqno >> (d - 1); - if y > 2 * x + 1 { - // ((x + 1) << d) <= req_seqno <=> (x+1) <= (req_seqno >> d) = (y >> 1) <=> 2*x+2 <= y <=> y > 2*x+1 - return Ok(TraverseNextStep::Stop); // all nodes in subtree have block.seqno < req_seqno => skip - } - return if y == 2 * x + 1 { - Ok(TraverseNextStep::VisitOne) // visit only right ("1") - } else { - Ok(TraverseNextStep::VisitZeroOne) // visit left, then right ("0" then "1") + match y.cmp(&(2 * x + 1)) { + std::cmp::Ordering::Greater => { + // ((x + 1) << d) <= req_seqno <=> (x+1) <= (req_seqno >> d) = (y >> 1) <=> 2*x+2 <= y <=> y > 2*x+1 + Ok(TraverseNextStep::Stop) // all nodes in subtree have block.seqno < req_seqno => skip + } + std::cmp::Ordering::Equal => { + Ok(TraverseNextStep::VisitOne) // visit only right ("1") + } + _ => { + Ok(TraverseNextStep::VisitZeroOne) // visit left, then right ("0" then "1") + } } })?; @@ -944,7 +951,7 @@ impl Deserializable for CreatorStats { if tag != Self::tag() { fail!( BlockError::InvalidConstructorTag { - t: tag.into(), + t: tag, s: "CreatorStats".to_string() } ) @@ -990,7 +997,7 @@ impl Deserializable for BlockCreateStats { if tag != Self::tag() { fail!( BlockError::InvalidConstructorTag { - t: tag.into(), + t: tag, s: "BlockCreateStats".to_string() } ) @@ -1044,7 +1051,7 @@ impl McStateExtra { pub fn add_workchain(&mut self, workchain_id: i32, descr: &ShardDescr) -> Result { let shards = BinTree::with_item(descr)?; self.shards.set(&workchain_id, &InRefValue(shards))?; - Ok(ShardIdent::with_workchain_id(workchain_id)?) + ShardIdent::with_workchain_id(workchain_id) } /// @@ -1099,7 +1106,7 @@ impl Deserializable for McStateExtra { self.shards.read_from(cell)?; self.config.read_from(cell)?; - let ref mut cell1 = cell.checked_drain_reference()?.into(); + let cell1 = &mut cell.checked_drain_reference()?.into(); let mut flags = 0u16; flags.read_from(cell1)?; if flags > 1 { @@ -1274,8 +1281,8 @@ impl ShardDescr { reg_mc_seqno: 0, start_lt, end_lt, - root_hash: root_hash, - file_hash: UInt256::default(), + root_hash, + file_hash: UInt256::ZERO, before_split: false, before_merge: false, want_split: false, @@ -1295,22 +1302,13 @@ impl ShardDescr { self.split_merge_at == other.split_merge_at } pub fn is_fsm_merge(&self) -> bool { - match self.split_merge_at { - FutureSplitMerge::Merge{merge_utime: _, interval: _} => true, - _ => false - } + matches!(self.split_merge_at, FutureSplitMerge::Merge{merge_utime: _, interval: _}) } pub fn is_fsm_split(&self) -> bool { - match self.split_merge_at { - FutureSplitMerge::Split{split_utime: _, interval: _} => true, - _ => false - } + matches!(self.split_merge_at, FutureSplitMerge::Split{split_utime: _, interval: _}) } pub fn is_fsm_none(&self) -> bool { - match self.split_merge_at { - FutureSplitMerge::None => true, - _ => false - } + matches!(self.split_merge_at, FutureSplitMerge::None) } pub fn fsm_utime(&self) -> u32 { match self.split_merge_at { diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 332b670..26eaf33 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -55,7 +55,7 @@ impl Deserializable for MerkleProof { } self.hash.read_from(cell)?; self.depth = cell.get_next_u16()?; - self.proof = cell.checked_drain_reference()?.clone(); + self.proof = cell.checked_drain_reference()?; if self.hash != Cell::hash(&self.proof, 0) { fail!( BlockError::WrongMerkleProof( @@ -335,14 +335,12 @@ pub fn check_message_proof(proof: &MerkleProof, msg: &Message, block_id: &UInt25 BlockError::WrongMerkleProof("Wrong message's hash in proof".to_string()) ) } else { - return Ok(()) + Ok(()) } } else { - fail!( - BlockError::WrongMerkleProof( - "Error extracting message from out message".to_string() - ) - ) + fail!(BlockError::WrongMerkleProof( + "Error extracting message from out message".to_string() + )) } } else { fail!(BlockError::WrongMerkleProof("No message in proof".to_string())) diff --git a/src/merkle_update.rs b/src/merkle_update.rs index 8c3e156..ec2e060 100644 --- a/src/merkle_update.rs +++ b/src/merkle_update.rs @@ -64,8 +64,8 @@ impl Deserializable for MerkleUpdate { self.new_hash.read_from(cell)?; self.old_depth = cell.get_next_u16()?; self.new_depth = cell.get_next_u16()?; - self.old = cell.checked_drain_reference()?.clone(); - self.new = cell.checked_drain_reference()?.clone(); + self.old = cell.checked_drain_reference()?; + self.new = cell.checked_drain_reference()?; if self.old_hash != Cell::hash(&self.old, 0) { fail!( @@ -318,7 +318,7 @@ impl MerkleUpdate { let mask = update_child.level_mask().mask(); if mask & (1 << child_merkle_depth) != 0 { // connect branch from old bag instead pruned - let new_child_hash = Cell::hash(&update_child, update_child.level() as usize - 1); + let new_child_hash = Cell::hash(update_child, update_child.level() as usize - 1); old_cells.get(&new_child_hash).unwrap().clone() } else { // else - just copy this cell (like an ordinary) @@ -388,7 +388,7 @@ impl MerkleUpdate { if let Some(common_cell) = new_cells.get(&child_hash) { let pruned_branch_cell = Self::make_pruned_branch_cell(common_cell, 0)?; - pruned_branches.insert(child_hash.clone(), pruned_branch_cell.clone().into_cell()?); + pruned_branches.insert(child_hash, pruned_branch_cell.clone().into_cell()?); childs[i] = Some(pruned_branch_cell); has_pruned = true; @@ -404,17 +404,16 @@ impl MerkleUpdate { let mut old_update_cell = BuilderData::new(); let mut child_mask = LevelMask::with_mask(0); - let mut i = 0; - for child_opt in childs { - let child = if child_opt.is_some() { - child_opt.unwrap() - } else { - let child = &old_cell.reference(i).unwrap(); - Self::make_pruned_branch_cell(child, 0)? + for (i, child_opt) in childs.into_iter().enumerate() { + let child = match child_opt { + None => { + let child = old_cell.reference(i).unwrap(); + Self::make_pruned_branch_cell(&child, 0)? + } + Some(child) => child }; child_mask |= child.level_mask(); old_update_cell.append_reference_cell(child.into_cell()?); - i += 1; } old_update_cell.set_level_mask(child_mask); @@ -440,8 +439,7 @@ impl MerkleUpdate { Ok(LevelMask::with_mask(mask | (1 << depth))) } - pub(crate) fn make_pruned_branch_cell(cell: &Cell, merkle_depth: u8) - -> Result { + pub(crate) fn make_pruned_branch_cell(cell: &Cell, merkle_depth: u8) -> Result { let mut result = BuilderData::new(); let level_mask = Self::add_one_hash(cell, merkle_depth)?; @@ -495,7 +493,7 @@ impl MerkleUpdate { known_cells.insert(hash, cell.clone()); let child_merkle_depth = if cell.is_merkle() { merkle_depth + 1 } else { merkle_depth }; for child in cell.clone_references().iter() { - Self::collate_old_cells(&child, known_cells_hashes, known_cells, visited, child_merkle_depth); + Self::collate_old_cells(child, known_cells_hashes, known_cells, visited, child_merkle_depth); } } } diff --git a/src/messages.rs b/src/messages.rs index 6fe50da..80ea4e0 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -301,7 +301,7 @@ impl FromStr for MsgAddress { } let address = SliceData::from_string(parts[len - 1])?; if len == 2 && parts[0].is_empty() { - return Ok(MsgAddress::with_extern(address)?) + return MsgAddress::with_extern(address) } let workchain_id = len.checked_sub(2) .map(|index| parts[index].parse::()).transpose() @@ -324,7 +324,8 @@ impl FromStr for MsgAddress { ) } ).transpose()? - .map(|value| AnycastInfo::with_rewrite_pfx(value)).transpose() + .map(AnycastInfo::with_rewrite_pfx) + .transpose() .map_err( |err| BlockError::InvalidArg( format!("anycast is not correct: {}", err) @@ -412,7 +413,7 @@ impl MsgAddressInt { pub fn get_rewrite_pfx(&self) -> Option { self.rewrite_pfx() } pub fn address(&self) -> AccountId { match self { - MsgAddressInt::AddrStd(addr_std) => addr_std.address.clone().into(), + MsgAddressInt::AddrStd(addr_std) => addr_std.address.clone(), MsgAddressInt::AddrVar(addr_var) => addr_var.address.clone() } } @@ -557,11 +558,10 @@ impl fmt::Display for MsgAddressIntOrNone { impl Serializable for MsgAddressIntOrNone { fn write_to(&self, cell: &mut BuilderData) -> Result<()> { match self { - MsgAddressIntOrNone::None => { + MsgAddressIntOrNone::None => { cell.append_raw(&[0x00], 2)?; - () - }, - MsgAddressIntOrNone::Some(addr) => addr.write_to(cell)?, + } + MsgAddressIntOrNone::Some(addr) => addr.write_to(cell)? } Ok(()) } @@ -889,14 +889,14 @@ impl CommonMsgInfo { /// Value can be transmitted only internal messages /// For other types of messages, function returned None /// - pub fn get_value<'a>(&'a self) -> Option<&'a CurrencyCollection> { + pub fn get_value(&self) -> Option<&CurrencyCollection> { match self { CommonMsgInfo::IntMsgInfo(header) => Some(&header.value), _ => None, } } - pub fn get_value_mut<'a>(&'a mut self) -> Option<&'a mut CurrencyCollection> { + pub fn get_value_mut(&mut self) -> Option<&mut CurrencyCollection> { match self { CommonMsgInfo::IntMsgInfo(header) => Some(&mut header.value), _ => None, @@ -1176,10 +1176,8 @@ impl Message { CommonMsgInfo::ExtOutMsgInfo(ref header) => &header.src, _ => &MsgAddressIntOrNone::None, }; - if let MsgAddressIntOrNone::Some(ref addr_int) = addr { - if let MsgAddressInt::AddrStd(ref addr_std) = addr_int { - return Some(addr_std.address.clone()); - } + if let MsgAddressIntOrNone::Some(MsgAddressInt::AddrStd(addr_std)) = addr { + return Some(addr_std.address.clone()) // TODO: What about AddrVar? } None @@ -1262,38 +1260,27 @@ impl Message { }; } pub fn set_src_address(&mut self, src: MsgAddressInt) { - match self.header { - CommonMsgInfo::IntMsgInfo(ref mut header) => { + match &mut self.header { + CommonMsgInfo::IntMsgInfo(header) => { header.src = MsgAddressIntOrNone::Some(src); } - CommonMsgInfo::ExtOutMsgInfo(ref mut header) => { + CommonMsgInfo::ExtOutMsgInfo(header) => { header.src = MsgAddressIntOrNone::Some(src); } _ => () }; } - pub fn set_dst_address(&mut self, dst: MsgAddressInt) { - match self.header { - CommonMsgInfo::IntMsgInfo(ref mut header) => { - header.dst = dst; - } - CommonMsgInfo::ExtInMsgInfo(ref mut header) => { - header.dst = dst; - } - _ => () - }; - } /// /// Get message's Unix time and logical time /// None only for internal and external outbound message /// pub fn at_and_lt(&self) -> Option<(u32, u64)> { - match self.header { - CommonMsgInfo::IntMsgInfo(ref header) => { + match &self.header { + CommonMsgInfo::IntMsgInfo(header) => { Some((header.created_at.0, header.created_lt)) }, - CommonMsgInfo::ExtOutMsgInfo(ref header) => { + CommonMsgInfo::ExtOutMsgInfo(header) => { Some((header.created_at.0, header.created_lt)) }, _ => None @@ -1315,14 +1302,25 @@ impl Message { /// /// Get value transmitted by the message /// - pub fn get_value<'a>(&'a self) -> Option<&'a CurrencyCollection> { + pub fn get_value(&self) -> Option<&CurrencyCollection> { self.value() } + + /// + /// Get value transmitted by the message + /// + pub fn value(&self) -> Option<&CurrencyCollection> { self.header.get_value() } /// /// Get value transmitted by the message /// - pub fn get_value_mut<'a>(&'a mut self) -> Option<&'a mut CurrencyCollection> { + pub fn get_value_mut(&mut self) -> Option<&mut CurrencyCollection> { self.value_mut() } + + + /// + /// Get value transmitted by the message + /// + pub fn value_mut(&mut self) -> Option<&mut CurrencyCollection> { self.body_to_ref = None; self.init_to_ref = None; self.header.get_value_mut() @@ -1341,30 +1339,21 @@ impl Message { /// Is message an internal? /// pub fn is_internal(&self) -> bool { - match self.header { - CommonMsgInfo::IntMsgInfo(_) => true, - _ => false - } + matches!(self.header, CommonMsgInfo::IntMsgInfo(_)) } /// /// Is message an external inbound? /// pub fn is_inbound_external(&self) -> bool { - match self.header { - CommonMsgInfo::ExtInMsgInfo(_) => true, - _ => false - } + matches!(self.header, CommonMsgInfo::ExtInMsgInfo(_)) } /// /// Is message an external outbound? /// pub fn is_outbound_external(&self) -> bool { - match self.header { - CommonMsgInfo::ExtOutMsgInfo(_) => true, - _ => false - } + matches!(self.header, CommonMsgInfo::ExtOutMsgInfo(_)) } /// @@ -1475,25 +1464,21 @@ impl Message { let (body_to_ref, init_to_ref) = if let (Some(b), Some(i)) = (body_to_ref, init_to_ref) { (*b, *i) + } else if header_bits + state_bits + body_bits <= MAX_DATA_BITS && + header_refs + state_refs + body_refs <= MAX_REFERENCES_COUNT { + // all fits into one cell + (false, false) + } else if header_bits + state_bits <= MAX_DATA_BITS && + header_refs + state_refs < MAX_REFERENCES_COUNT { // + body cell ref + // header & state fit + (true, false) + } else if header_bits + body_bits <= MAX_DATA_BITS && + header_refs + body_refs < MAX_REFERENCES_COUNT { // + init cell ref + // header & body fit + (false, true) } else { - if header_bits + state_bits + body_bits <= MAX_DATA_BITS && - header_refs + state_refs + body_refs <= MAX_REFERENCES_COUNT { - // all fits into one cell - (false, false) - } else { - if header_bits + state_bits <= MAX_DATA_BITS && - header_refs + state_refs + 1 <= MAX_REFERENCES_COUNT { // + body cell ref - // header & state fit - (true, false) - } else if header_bits + body_bits <= MAX_DATA_BITS && - header_refs + body_refs + 1 <= MAX_REFERENCES_COUNT { // + init cell ref - // header & body fit - (false, true) - } else { - // only header fits - (true, true) - } - } + // only header fits + (true, true) }; // write StateInit @@ -1789,13 +1774,13 @@ impl Deserializable for StateInit { self.special = TickTock::read_maybe_from(cell)?; // code:(Maybe ^Cell) self.code = match cell.get_next_bit()? { - true => Some(cell.checked_drain_reference()?.clone()), + true => Some(cell.checked_drain_reference()?), false => None, }; // data:(Maybe ^Cell) self.data = match cell.get_next_bit()? { - true => Some(cell.checked_drain_reference()?.clone()), + true => Some(cell.checked_drain_reference()?), false => None, }; diff --git a/src/out_actions.rs b/src/out_actions.rs index e89e9af..b66a308 100644 --- a/src/out_actions.rs +++ b/src/out_actions.rs @@ -74,7 +74,7 @@ impl Deserializable for OutActions { fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { let mut cell = cell.clone(); while cell.remaining_references() != 0 { - let prev_cell = cell.checked_drain_reference()?.clone(); + let prev_cell = cell.checked_drain_reference()?; let mut action = OutAction::default(); action.read_from(&mut cell)?; self.push_front(action); @@ -171,7 +171,7 @@ pub const RESERVE_VALID_MODES: u8 = pub const CHANGE_LIB_REMOVE: u8 = 0; pub const SET_LIB_CODE_REMOVE: u8 = 1; -pub const SET_LIB_CODE_ADD_PRIVATE: u8 = 1 * 2 + 1; +pub const SET_LIB_CODE_ADD_PRIVATE: u8 = 2 + 1; pub const SET_LIB_CODE_ADD_PUBLIC: u8 = 2 * 2 + 1; /// @@ -218,21 +218,21 @@ impl OutAction { impl Serializable for OutAction { fn write_to(&self, cell: &mut BuilderData) -> Result<()> { match self { - &OutAction::SendMsg{ref mode, ref out_msg} => { + OutAction::SendMsg{ref mode, ref out_msg} => { ACTION_SEND_MSG.write_to(cell)?; // tag mode.write_to(cell)?; cell.append_reference_cell(out_msg.serialize()?); - }, - &OutAction::SetCode{ref new_code} => { + } + OutAction::SetCode{ref new_code} => { ACTION_SET_CODE.write_to(cell)?; //tag cell.append_reference_cell(new_code.clone()); - }, - &OutAction::ReserveCurrency{ref mode, ref value} => { + } + OutAction::ReserveCurrency{ref mode, ref value} => { ACTION_RESERVE.write_to(cell)?; // tag mode.write_to(cell)?; value.write_to(cell)?; - }, - &OutAction::ChangeLibrary{ref mode, ref code, ref hash} => { + } + OutAction::ChangeLibrary{ref mode, ref code, ref hash} => { ACTION_CHANGE_LIB.write_to(cell)?; // tag mode.write_to(cell)?; if let Some(value) = hash { @@ -241,8 +241,8 @@ impl Serializable for OutAction { if let Some(value) = code { cell.append_reference_cell(value.clone()); } - }, - &OutAction::None => fail!( + } + OutAction::None => fail!( BlockError::InvalidOperation("self is None".to_string()) ) } @@ -265,7 +265,7 @@ impl Deserializable for OutAction { *self = OutAction::new_send(mode, msg); } ACTION_SET_CODE => { - *self = OutAction::new_set(cell.checked_drain_reference()?.clone()) + *self = OutAction::new_set(cell.checked_drain_reference()?) } ACTION_RESERVE => { let mut mode = 0u8; @@ -283,7 +283,7 @@ impl Deserializable for OutAction { *self = OutAction::new_change_library(mode, None, Some(hash)); } _ => { - let code = cell.checked_drain_reference()?.clone(); + let code = cell.checked_drain_reference()?; *self = OutAction::new_change_library(mode, Some(code), None); } } diff --git a/src/outbound_messages.rs b/src/outbound_messages.rs index 387610c..fd75589 100644 --- a/src/outbound_messages.rs +++ b/src/outbound_messages.rs @@ -152,7 +152,7 @@ impl OutMsgDescr { } pub fn full_exported(&self) -> &CurrencyCollection { - &self.root_extra() + self.root_extra() } } @@ -217,6 +217,7 @@ impl OutMsgQueueKey { acc.clone().get_next_u64().unwrap() } + // #[deprecated(note = "use Display converter in format!")] pub fn to_hex_string(&self) -> String { format!("{}:{:016X}, hash: {:x}", self.workchain_id, self.prefix, self.hash) } @@ -507,14 +508,14 @@ impl OutMsg { pub fn message_cell(&self) -> Result> { Ok( match self { - OutMsg::External(ref x) => Some(x.message_cell().clone()), - OutMsg::Immediately(ref x) => Some(x.read_out_message()?.message_cell().clone()), - OutMsg::New(ref x) => Some(x.read_out_message()?.message_cell().clone()), - OutMsg::Transit(ref x) => Some(x.read_out_message()?.message_cell().clone()), - OutMsg::Dequeue(ref x) => Some(x.read_out_message()?.message_cell().clone()), + OutMsg::External(ref x) => Some(x.message_cell()), + OutMsg::Immediately(ref x) => Some(x.read_out_message()?.message_cell()), + OutMsg::New(ref x) => Some(x.read_out_message()?.message_cell()), + OutMsg::Transit(ref x) => Some(x.read_out_message()?.message_cell()), + OutMsg::Dequeue(ref x) => Some(x.read_out_message()?.message_cell()), OutMsg::DequeueShort(_) => None, - OutMsg::DequeueImmediately(ref x) => Some(x.read_out_message()?.message_cell().clone()), - OutMsg::TransitRequeued(ref x) => Some(x.read_out_message()?.message_cell().clone()), + OutMsg::DequeueImmediately(ref x) => Some(x.read_out_message()?.message_cell()), + OutMsg::TransitRequeued(ref x) => Some(x.read_out_message()?.message_cell()), OutMsg::None => fail!("wrong message type") } ) @@ -590,31 +591,31 @@ impl Augmentation for OutMsg { let env = x.read_out_message()?; let msg = env.read_message()?; // exported value = msg.value + msg.ihr_fee + fwd_fee_remaining - exported.add(&msg.header().get_value().unwrap())?; + exported.add(msg.header().get_value().unwrap())?; if let CommonMsgInfo::IntMsgInfo(header) = msg.header() { exported.grams.add(&header.ihr_fee)?; } - exported.grams.add(&env.fwd_fee_remaining())?; + exported.grams.add(env.fwd_fee_remaining())?; } OutMsg::Transit(ref x) => { let env = x.read_out_message()?; let msg = env.read_message()?; // exported value = msg.value + msg.ihr_fee + fwd_fee_remaining - exported.add(&msg.header().get_value().unwrap())?; + exported.add(msg.header().get_value().unwrap())?; if let CommonMsgInfo::IntMsgInfo(header) = msg.header() { exported.grams.add(&header.ihr_fee)?; } - exported.grams.add(&env.fwd_fee_remaining())?; + exported.grams.add(env.fwd_fee_remaining())?; } OutMsg::TransitRequeued(ref x) => { let env = x.read_out_message()?; let msg = env.read_message()?; // exported value = msg.value + msg.ihr_fee + fwd_fee_remaining - exported.add(&msg.header().get_value().unwrap())?; + exported.add(msg.header().get_value().unwrap())?; if let CommonMsgInfo::IntMsgInfo(header) = msg.header() { exported.grams.add(&header.ihr_fee)?; } - exported.grams.add(&env.fwd_fee_remaining())?; + exported.grams.add(env.fwd_fee_remaining())?; } OutMsg::None => fail!("wrong OutMsg type"), // for other types - no value exported @@ -674,7 +675,7 @@ impl Deserializable for OutMsg { OUT_MSG_TR => read_out_msg_descr!(cell, OutMsgTransit, Transit), OUT_MSG_DEQ_IMM => read_out_msg_descr!(cell, OutMsgDequeueImmediately, DequeueImmediately), OUT_MSG_TRDEQ => read_out_msg_descr!(cell, OutMsgTransitRequeued, TransitRequeued), - tag if cell.remaining_bits() > 0 && (tag == OUT_MSG_DEQ >> 1 || tag == OUT_MSG_DEQ_SHORT >> 1) => { + tag if cell.remaining_bits() != 0 && (tag == OUT_MSG_DEQ >> 1 || tag == OUT_MSG_DEQ_SHORT >> 1) => { match (tag << 1) | cell.get_next_bit_int().unwrap() as u8 { OUT_MSG_DEQ => read_out_msg_descr!(cell, OutMsgDequeue, Dequeue), OUT_MSG_DEQ_SHORT => read_out_msg_descr!(cell, OutMsgDequeueShort, DequeueShort), diff --git a/src/shard.rs b/src/shard.rs index 602093e..4e1fbc0 100644 --- a/src/shard.rs +++ b/src/shard.rs @@ -153,7 +153,7 @@ impl AccountIdPrefixFull { /// (using count from IntermediateAddress::Regular) pub fn interpolate_addr_intermediate(&self, dest: &Self, ia: &IntermediateAddress) -> Result { if let IntermediateAddress::Regular(regular) = ia { - Ok(self.interpolate_addr(&dest, regular.use_dest_bits())) + Ok(self.interpolate_addr(dest, regular.use_dest_bits())) } else { fail!("IntermediateAddress::Regular is expected") } @@ -176,6 +176,7 @@ impl AccountIdPrefixFull { /// Result: (transit_addr_dest_bits, nh_addr_dest_bits) /// TBD #[allow(dead_code)] + #[allow(clippy::many_single_char_names)] pub(crate) fn perform_hypercube_routing( &self, dest: &AccountIdPrefixFull, @@ -187,7 +188,7 @@ impl AccountIdPrefixFull { fail!("Shard {} must fully contain transit prefix {}", cur_shard, transit) } - if cur_shard.contains_full_prefix(&dest) { + if cur_shard.contains_full_prefix(dest) { // If destination is in this shard, set cur:=next_hop:=dest return Ok((IntermediateAddress::full_dest(), IntermediateAddress::full_dest())) } @@ -299,7 +300,7 @@ impl ShardIdent { let mut shard_prefix = 0; while let Some(bit) = shard_prefix_slice.get_next_bit_opt() { shard_pfx_bits += 1; - shard_prefix = shard_prefix | ((bit as u64) << 64 - shard_pfx_bits) + shard_prefix |= (bit as u64) << (64 - shard_pfx_bits) } if shard_pfx_bits > MAX_SPLIT_DEPTH { fail!( @@ -538,7 +539,7 @@ impl ShardIdent { self.prefix } - pub fn shard_prefix_without_tag(self) -> u64 { + pub fn shard_prefix_without_tag(&self) -> u64 { self.prefix - self.prefix_lower_bits() } @@ -570,7 +571,7 @@ impl ShardIdent { pub fn split(&self) -> Result<(ShardIdent, ShardIdent)> { let lb = self.prefix_lower_bits() >> 1; - if lb & (!0 >> MAX_SPLIT_DEPTH + 1) != 0 { + if lb & (!0 >> (MAX_SPLIT_DEPTH + 1)) != 0 { fail!( BlockError::InvalidArg( format!("Can't split shard {}, because of max split depth is {}", @@ -598,7 +599,7 @@ impl ShardIdent { // TODO: need to check max split first pub fn right_ancestor_mask(&self) -> Result { - Self::with_tagged_prefix(self.workchain_id, self.prefix + (1 << 64 - MAX_SPLIT_DEPTH)) + Self::with_tagged_prefix(self.workchain_id, self.prefix + (1 << (64 - MAX_SPLIT_DEPTH))) } // returns all 0 and first 1 from right to left @@ -834,9 +835,10 @@ pub struct ShardStateUnsplit { impl ShardStateUnsplit { pub fn with_ident(shard_id: ShardIdent) -> Self { - let mut shard_state = ShardStateUnsplit::default(); - shard_state.shard_id = shard_id; - shard_state + Self { + shard_id, + ..ShardStateUnsplit::default() + } } pub fn id(&self) -> String { @@ -1095,7 +1097,7 @@ impl Deserializable for ShardStateUnsplit { self.before_split = cell.get_next_bit()?; self.accounts.read_from_reference(cell)?; - let ref mut cell1 = cell.checked_drain_reference()?.into(); + let cell1 = &mut cell.checked_drain_reference()?.into(); self.overload_history.read_from(cell1)?; self.underload_history.read_from(cell1)?; self.total_balance.read_from(cell1)?; diff --git a/src/signature.rs b/src/signature.rs index 88e88cc..a2bd65f 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -50,7 +50,7 @@ impl CryptoSignature { Ok(Self(ed25519::Signature::from_bytes(bytes)?)) } - #[deprecated] + // #[deprecated] pub fn from_str(s: &str) -> Result { FromStr::from_str(s) } pub fn from_r_s(r: &[u8], s: &[u8]) -> Result @@ -64,8 +64,8 @@ impl CryptoSignature { let mut sign = [0_u8; ed25519_dalek::SIGNATURE_LENGTH]; { let mut cur = Cursor::new(&mut sign[..]); - cur.write(r).unwrap(); - cur.write(s).unwrap(); + cur.write_all(r).unwrap(); + cur.write_all(s).unwrap(); } Ok(Self(ed25519::Signature::from_bytes(&sign[..])?)) } @@ -211,7 +211,7 @@ impl SigPubKey { Ok(SigPubKey(ed25519_dalek::PublicKey::from_bytes(bytes)?)) } - #[deprecated] + // #[deprecated] pub fn from_str(s: &str) -> Result { FromStr::from_str(s) } pub fn key(&self) -> &ed25519_dalek::PublicKey { @@ -365,7 +365,7 @@ impl BlockSignaturesPure { self.signatures().iterate_slices(|ref mut _key, ref mut slice| { let sign = CryptoSignaturePair::construct_from(slice)?; if let Some(vd) = validators_map.get(&sign.node_id_short) { - if !vd.public_key.verify_signature(data, &sign.sign) { + if !vd.verify_signature(data, &sign.sign) { fail!(BlockError::BadSignature) } weight += vd.weight; @@ -530,7 +530,7 @@ impl Deserializable for BlockProof { ) } self.proof_for.read_from(cell)?; - self.root = cell.checked_drain_reference()?.clone(); + self.root = cell.checked_drain_reference()?; self.signatures = if cell.get_next_bit()? { Some(BlockSignatures::construct_from_reference(cell)?) } else { diff --git a/src/signed_block.rs b/src/signed_block.rs index b5f10fd..94006d9 100644 --- a/src/signed_block.rs +++ b/src/signed_block.rs @@ -58,9 +58,7 @@ impl Deserializable for BlockSignature { impl Default for BlockSignature { fn default() -> Self { BlockSignature( - ed25519::Signature::from_bytes( - &vec!(0; ed25519_dalek::SIGNATURE_LENGTH) - ).unwrap() + ed25519::Signature::from_bytes(&[0; ed25519_dalek::SIGNATURE_LENGTH]).unwrap() ) } } @@ -107,8 +105,8 @@ impl SignedBlock { // hashes calculation let serlz_hash = Self::calc_merkle_hash(&serialized_block)?; let mut combined_data = Vec::::with_capacity(SHA256_SIZE * 2); - combined_data.write(block_root.repr_hash().as_slice()).unwrap(); - combined_data.write(&serlz_hash).unwrap(); + combined_data.write_all(block_root.repr_hash().as_slice()).unwrap(); + combined_data.write_all(&serlz_hash).unwrap(); let mut hasher = sha2::Sha256::new(); hasher.input(combined_data.as_slice()); @@ -144,13 +142,13 @@ impl SignedBlock { &self.signatures } - pub fn add_signature(self: &mut Self, key: &ed25519_dalek::Keypair) { + pub fn add_signature(&mut self, key: &ed25519_dalek::Keypair) { let signature = key.sign(self.combined_hash.as_slice()); let key = super::id_from_key(&key.public); self.signatures.insert(key, BlockSignature {0: signature}); } - pub fn verify_signature(self: &Self, key: &ed25519_dalek::PublicKey) -> Result { + pub fn verify_signature(&self, key: &ed25519_dalek::PublicKey) -> Result { let key_id = super::id_from_key(key); let signature = match self.signatures.get(&key_id) { Some(s) => &s.0, @@ -159,7 +157,7 @@ impl SignedBlock { Ok(key.verify(self.combined_hash.as_slice(), signature).is_ok()) } - pub fn write_to(self: &Self, dest: &mut T) -> Result<()> { + pub fn write_to(&self, dest: &mut T) -> Result<()> { // Transform signed block into tree of cells // // signed_block @@ -179,7 +177,7 @@ impl SignedBlock { // Write signed block's bytes and then unsigned block's bytes bag.write_to(dest, true)?; - dest.write(&self.serialized_block)?; + dest.write_all(&self.serialized_block)?; Ok(()) } @@ -235,7 +233,7 @@ impl SignedBlock { let n = Self::largest_power_of_two_less_than(l); let data1_hash = Self::calc_merkle_hash(&data[..n])?; let data2_hash = Self::calc_merkle_hash(&data[n..])?; - let mut data_for_hash = [0 as u8; 8 + SHA256_SIZE * 2]; + let mut data_for_hash = [0; 8 + SHA256_SIZE * 2]; data_for_hash[..8].copy_from_slice(&(l as u64).to_be_bytes()); data_for_hash[8..8 + SHA256_SIZE].copy_from_slice(&data1_hash); data_for_hash[8 + SHA256_SIZE..].copy_from_slice(&data2_hash); diff --git a/src/transactions.rs b/src/transactions.rs index 398df25..1e16d94 100644 --- a/src/transactions.rs +++ b/src/transactions.rs @@ -189,7 +189,7 @@ impl TrComputePhase { pub fn get_vmphase_mut(&mut self) -> Option<&mut TrComputePhaseVm> { match self { - TrComputePhase::Vm(ref mut vm_ref) => return Some(vm_ref), + TrComputePhase::Vm(ref mut vm_ref) => Some(vm_ref), _ => None, } } @@ -254,38 +254,46 @@ impl Serializable for TrComputePhase { } impl Deserializable for TrComputePhase { - fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { - + fn construct_from(cell: &mut SliceData) -> Result { if !cell.get_next_bit()? { - // tr_phase_compute_skipped$0clear - let mut s = TrComputePhaseSkipped::default(); - s.reason.read_from(cell)?;// reason:ComputeSkipReason - *self = TrComputePhase::Skipped(s); + let reason = Deserializable::construct_from(cell)?; + Ok(TrComputePhase::Skipped(TrComputePhaseSkipped { reason })) } else { // tr_phase_compute_vm$1 - let mut v = TrComputePhaseVm::default(); - - v.success = cell.get_next_bit()?; // success:Bool - v.msg_state_used = cell.get_next_bit()?; // msg_state_used:Bool - v.account_activated = cell.get_next_bit()?; // account_activated:Bool - v.gas_fees.read_from(cell)?; // gas_fees:Gram + let success = cell.get_next_bit()?; // success:Bool + let msg_state_used = cell.get_next_bit()?; // msg_state_used:Bool + let account_activated = cell.get_next_bit()?; // account_activated:Bool + let gas_fees = Deserializable::construct_from(cell)?; // gas_fees:Gram // fields below are serialized into separate cell - let mut sep_cell = cell.checked_drain_reference()?.into(); - - v.gas_used.read_from(&mut sep_cell)?; // gas_used:(VarUInteger 7) - v.gas_limit.read_from(&mut sep_cell)?; // gas_limit:(VarUInteger 7) - v.gas_credit = VarUInteger3::read_maybe_from(&mut sep_cell)?; // gas_credit:(Maybe (VarUInteger 3)) - v.mode = sep_cell.get_next_byte()? as i8; // mode:int8 - v.exit_code = sep_cell.get_next_u32()? as i32; // exit_code:int32 - v.exit_arg = i32::read_maybe_from(&mut sep_cell)?; // exit_arg:(Maybe int32) - v.vm_steps = sep_cell.get_next_u32()?; // vm_steps:uint32 - v.vm_init_state_hash.read_from(&mut sep_cell)?; // vm_init_state_hash:uint256 - v.vm_final_state_hash.read_from(&mut sep_cell)?; // vm_final_state_hash:uint256 - - *self = TrComputePhase::Vm(v); + let sep_cell = &mut cell.checked_drain_reference()?.into(); + + let gas_used = Deserializable::construct_from(sep_cell)?; // gas_used:(VarUInteger 7) + let gas_limit = Deserializable::construct_from(sep_cell)?; // gas_limit:(VarUInteger 7) + let gas_credit = Deserializable::construct_maybe_from(sep_cell)?; // gas_credit:(Maybe (VarUInteger 3)) + let mode = Deserializable::construct_from(sep_cell)?; // mode:int8 + let exit_code = Deserializable::construct_from(sep_cell)?; // exit_code:int32 + let exit_arg = Deserializable::construct_maybe_from(sep_cell)?; // exit_arg:(Maybe int32) + let vm_steps = Deserializable::construct_from(sep_cell)?; // vm_steps:uint32 + let vm_init_state_hash = Deserializable::construct_from(sep_cell)?; // vm_init_state_hash:uint256 + let vm_final_state_hash = Deserializable::construct_from(sep_cell)?; // vm_final_state_hash:uint256 + let v = TrComputePhaseVm { + success, + msg_state_used, + account_activated, + gas_fees, + gas_used, + gas_limit, + gas_credit, + mode, + exit_code, + exit_arg, + vm_steps, + vm_init_state_hash, + vm_final_state_hash + }; + Ok(TrComputePhase::Vm(v)) } - Ok(()) } } @@ -304,7 +312,15 @@ pub struct TrStoragePhase { } impl TrStoragePhase { - pub fn with_params(collected: Grams, due: Option, status: AccStatusChange) -> Self { + pub fn new() -> Self { + Self { + storage_fees_collected: Grams::default(), + storage_fees_due: None, + status_change: AccStatusChange::default() + + } + } + pub const fn with_params(collected: Grams, due: Option, status: AccStatusChange) -> Self { TrStoragePhase { storage_fees_collected: collected, storage_fees_due: due, @@ -419,17 +435,15 @@ impl Deserializable for TrBouncePhase { bp.msg_fees.read_from(cell)?; // msg_fees:Grams bp.fwd_fees.read_from(cell)?; // fwd_fees:Grams *self = TrBouncePhase::Ok(bp); + } else if cell.get_next_bit()? { + // tr_phase_bounce_nofunds$01 + let mut bp = TrBouncePhaseNofunds::default(); + bp.msg_size.read_from(cell)?; // msg_size:StorageUsed + bp.req_fwd_fees.read_from(cell)?; // req_fwd_fees:Grams + *self = TrBouncePhase::Nofunds(bp); } else { - if cell.get_next_bit()? { - // tr_phase_bounce_nofunds$01 - let mut bp = TrBouncePhaseNofunds::default(); - bp.msg_size.read_from(cell)?; // msg_size:StorageUsed - bp.req_fwd_fees.read_from(cell)?; // req_fwd_fees:Grams - *self = TrBouncePhase::Nofunds(bp); - } else { - //tr_phase_bounce_negfunds$00 - *self = TrBouncePhase::Negfunds; - } + //tr_phase_bounce_negfunds$00 + *self = TrBouncePhase::Negfunds; } Ok(()) } @@ -467,7 +481,10 @@ pub struct TrCreditPhase { } impl TrCreditPhase { - pub fn with_params(due_fees_collected: Option, credit: CurrencyCollection) -> Self { + pub const fn default() -> Self { + TrCreditPhase::with_params(None, CurrencyCollection::default()) + } + pub const fn with_params(due_fees_collected: Option, credit: CurrencyCollection) -> Self { TrCreditPhase { due_fees_collected, credit, @@ -746,14 +763,16 @@ pub struct TransactionDescrTickTock { impl TransactionDescrTickTock { pub fn tick() -> Self { - let mut descr = Self::default(); - descr.tt = TransactionTickTock::Tick; - descr + Self { + tt: TransactionTickTock::Tick, + ..Self::default() + } } pub fn tock() -> Self { - let mut descr = Self::default(); - descr.tt = TransactionTickTock::Tock; - descr + Self { + tt: TransactionTickTock::Tock, + ..Self::default() + } } } @@ -1025,19 +1044,11 @@ impl TransactionDescr { } pub fn is_split(&self) -> bool { - match self { - TransactionDescr::SplitPrepare(_) | - TransactionDescr::SplitInstall(_) => true, - _ => false, - } + matches!(self, TransactionDescr::SplitPrepare(_) | TransactionDescr::SplitInstall(_)) } pub fn is_merge(&self) -> bool { - match self { - TransactionDescr::MergePrepare(_) | - TransactionDescr::MergeInstall(_) => true, - _ => false, - } + matches!(self, TransactionDescr::MergePrepare(_) | TransactionDescr::MergeInstall(_)) } fn append_to_storage_used(&mut self, cell: &Cell) { @@ -1328,7 +1339,7 @@ impl Transaction { } /// Get account address of transaction - pub fn account_id<'a>(&'a self) -> &'a AccountId { + pub fn account_id(&self) -> &AccountId { &self.account_addr } @@ -1378,11 +1389,6 @@ impl Transaction { /// get total fees pub fn total_fees(&self) -> &CurrencyCollection { &self.total_fees } - /// get mutable total fees - pub fn total_fees_mut(&mut self) -> &mut CurrencyCollection { - &mut self.total_fees - } - /// /// Calculate total transaction fees /// transaction fees is the amount fee for all out-messages @@ -1434,7 +1440,7 @@ impl Transaction { /// add output message to Hashmap pub fn add_out_message(&mut self, mgs: &Message) -> Result<()> { - let msg_cell = mgs.serialize()?.into(); + let msg_cell = mgs.serialize()?; let mut descr = self.read_description()?; descr.append_to_storage_used(&msg_cell); @@ -1513,9 +1519,7 @@ impl Transaction { ) )?; - MerkleProof::create_by_usage_tree(block_root, usage_tree) - .and_then(|proof| proof.serialize()) - .map(|cell| cell.into()) + MerkleProof::create_by_usage_tree(block_root, usage_tree)?.serialize() } pub fn contains_out_msg(&self, msg: &Message, hash: &UInt256) -> bool { @@ -1634,7 +1638,7 @@ impl Deserializable for Transaction { self.outmsg_cnt = cell.get_next_int(15)? as i16; // outmsg_cnt self.orig_status.read_from(cell)?; // orig_status self.end_status.read_from(cell)?; // end_status - let ref mut cell1 = SliceData::from(cell.checked_drain_reference()?); + let cell1 = &mut SliceData::from(cell.checked_drain_reference()?); if cell1.get_next_bit()? { let mut msg = ChildCell::default(); msg.read_from_reference(cell1)?; @@ -1700,7 +1704,7 @@ impl AccountBlock { let mut transactions = Transactions::default(); transactions.setref( &transaction.logical_time(), - &transaction.serialize()?.into(), + &transaction.serialize()?, transaction.total_fees() )?; Ok(AccountBlock { @@ -1720,7 +1724,7 @@ impl AccountBlock { /// add transaction to block pub fn add_transaction(&mut self, transaction: &Transaction) -> Result<()> { - self.add_serialized_transaction(transaction, &transaction.serialize()?.into()) + self.add_serialized_transaction(transaction, &transaction.serialize()?) } /// append serialized transaction to block (use to increase speed) @@ -1854,13 +1858,13 @@ impl ShardAccountBlocks { self.set_builder_serialized( account_block.account_addr.clone(), &account_block.write_to_new_cell()?, - &account_block.total_fee() + account_block.total_fee() ).map(|_|()) } /// adds transaction to account by id from transaction pub fn add_transaction(&mut self, transaction: &Transaction) -> Result<()> { - self.add_serialized_transaction(transaction, &transaction.serialize()?.into()) + self.add_serialized_transaction(transaction, &transaction.serialize()?) } pub fn add_serialized_transaction(&mut self, transaction: &Transaction, transaction_cell: &Cell) -> Result<()> { @@ -1884,7 +1888,7 @@ impl ShardAccountBlocks { }; // append transaction to AccountBlock account_block.add_serialized_transaction(transaction, transaction_cell)?; - self.set_builder_serialized(account_id.clone(), &account_block.write_to_new_cell()?, &transaction.total_fees())?; + self.set_builder_serialized(account_id.clone(), &account_block.write_to_new_cell()?, transaction.total_fees())?; Ok(()) } @@ -1898,7 +1902,7 @@ impl ShardAccountBlocks { } pub fn full_transaction_fees(&self) -> &CurrencyCollection { - &self.root_extra() + self.root_extra() } } diff --git a/src/types.rs b/src/types.rs index be65c47..fd3a980 100644 --- a/src/types.rs +++ b/src/types.rs @@ -47,7 +47,7 @@ use crate::{ macro_rules! define_VarIntegerN { ( $varname:ident, $N:expr, BigInt ) => { - #[derive( Eq, Hash, Clone, Debug)] + #[derive( Eq, Clone, Debug)] pub struct $varname(pub BigInt); #[allow(dead_code)] @@ -199,7 +199,7 @@ macro_rules! define_VarIntegerN { } }; ( $varname:ident, $N:expr, $tt:ty ) => { - #[derive( Eq, Hash, Clone, Debug, Default, Ord, PartialEq, PartialOrd)] + #[derive( Eq, Clone, Debug, Default, Ord, PartialEq, PartialOrd)] pub struct $varname(pub $tt); impl $varname { @@ -477,7 +477,7 @@ impl CurrencyCollection { } pub fn set_other_ex(&mut self, key: u32, other: &VarUInteger32) -> Result<()> { - self.other.set(&key, &other)?; + self.other.set(&key, other)?; Ok(()) } @@ -958,6 +958,7 @@ impl From for UnixTime32 { } } +#[allow(clippy::from_over_into)] impl Into for UnixTime32 { fn into(self) -> u32 { self.0 @@ -1024,7 +1025,7 @@ impl ChildCell { BlockError::PrunedCellAccess(std::any::type_name::().into()) ) } - T::construct_from(&mut SliceData::from(cell.clone())) + T::construct_from(&mut SliceData::from(cell)) } None => Ok(T::default()) } diff --git a/src/validators.rs b/src/validators.rs index b5979cb..aaddce9 100644 --- a/src/validators.rs +++ b/src/validators.rs @@ -14,7 +14,7 @@ use crate::{ define_HashmapE, error::BlockError, - signature::SigPubKey, + signature::{CryptoSignature, SigPubKey}, types::{Number16, UnixTime32}, Serializable, Deserializable, config_params::CatchainConfig, @@ -193,9 +193,17 @@ impl ValidatorDescr { let mut hasher = Sha256::new(); let magic = [0xc6, 0xb4, 0x13, 0x48]; // magic 0x4813b4c6 from original node's code 1209251014 for KEY_ED25519 hasher.input(&magic); - hasher.input(self.public_key.key_bytes()); + hasher.input(self.public_key.as_slice()); From::<[u8; 32]>::from(hasher.result().into()) } + + pub fn verify_signature(&self, data: &[u8], signature: &CryptoSignature) -> bool { + match SigPubKey::from_bytes(self.public_key.as_slice()) { + Ok(pub_key) => pub_key.verify_signature(data, signature), + _ => false + } + } + } const VALIDATOR_DESC_TAG: u8 = 0x53; @@ -281,18 +289,24 @@ pub struct ValidatorSet { list: Vec, //ValidatorDescriptions, } -#[derive(Eq, PartialEq, PartialOrd, Debug)] +#[derive(Eq, PartialEq, Debug)] struct IncludedValidatorWeight { pub prev_weight_sum: u64, pub weight: u64, } +impl PartialOrd for IncludedValidatorWeight { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl Ord for IncludedValidatorWeight { fn cmp(&self, other: &Self) -> Ordering { match self.prev_weight_sum.cmp(&other.prev_weight_sum) { Ordering::Equal => { self.weight.cmp(&other.weight) - }, + } other => other } } @@ -320,10 +334,10 @@ impl ValidatorSet { fail!(BlockError::InvalidArg("`list` can't be empty".to_string())) } let mut total_weight = 0; - for i in 0..list.len() { - list[i].prev_weight_sum = total_weight; - total_weight = total_weight.checked_add(list[i].weight).ok_or_else(|| - BlockError::InvalidData(format!("Validator's total weight is more than 2^64")) + for descr in &mut list { + descr.prev_weight_sum = total_weight; + total_weight = total_weight.checked_add(descr.weight).ok_or_else(|| + BlockError::InvalidData("Validator's total weight is more than 2^64".to_string()) )?; } Ok(ValidatorSet { @@ -399,7 +413,7 @@ impl ValidatorSet { pub fn at_weight(&self, weight_pos: u64) -> &ValidatorDescr { debug_assert!(weight_pos < self.total_weight); - debug_assert!(self.list.len() > 0); + debug_assert!(!self.list.is_empty()); for i in 0..self.list.len() { if self.list[i].prev_weight_sum > weight_pos { debug_assert!(i != 0); @@ -434,8 +448,8 @@ impl ValidatorSet { indexes[j] = i; } let mut subset = Vec::with_capacity(count); - for i in 0..count { - subset.push(self.list()[indexes[i]].clone()); + for index in indexes.iter().take(count) { + subset.push(self.list()[*index].clone()); } subset } @@ -501,20 +515,20 @@ impl ValidatorSet { subset }; - let hash_short = Self::calc_subset_hash_short(&subset, cc_seqno)?; + let hash_short = Self::calc_subset_hash_short(subset.as_slice(), cc_seqno)?; Ok((subset, hash_short)) } const HASH_SHORT_MAGIC: u32 = 0x901660ED; - pub fn calc_subset_hash_short(subset: &Vec, cc_seqno: u32) -> Result { + pub fn calc_subset_hash_short(subset: &[ValidatorDescr], cc_seqno: u32) -> Result { let mut hasher = crc32::Digest::new(crc32::CASTAGNOLI); hasher.write(&Self::HASH_SHORT_MAGIC.to_le_bytes()); hasher.write(&cc_seqno.to_le_bytes()); hasher.write(&(subset.len() as u32).to_le_bytes()); for vd in subset.iter() { - hasher.write(vd.public_key.key_bytes()); + hasher.write(vd.public_key.as_slice()); hasher.write(&vd.weight.to_le_bytes()); if let Some(addr) = vd.adnl_addr.as_ref() { hasher.write(addr.as_slice()); @@ -580,16 +594,12 @@ impl Deserializable for ValidatorSet { self.list.push(val); } if self.list.is_empty() { - failure::bail!(BlockError::InvalidData("list can't be empty".to_string())); + fail!(BlockError::InvalidData("list can't be empty".to_string())); } if tag == VALIDATOR_SET_TAG { self.total_weight = self.list.iter().map(|vd| vd.weight).sum(); - } else { - if self.total_weight != total_weight { - failure::bail!( - BlockError::InvalidData("Calculated total_weight is not equal to the read one while read ValidatorSet".to_string()) - ) - } + } else if self.total_weight != total_weight { + fail!(BlockError::InvalidData("Calculated total_weight is not equal to the read one while read ValidatorSet".to_string())) } if self.main > self.total { @@ -623,10 +633,10 @@ impl ValidatorSetPRNG { // u32 cc_seqno; let mut context = [0_u8; 48]; let mut cur = Cursor::new(&mut context[..]); - cur.write(seed).unwrap(); - cur.write(&shard_pfx.to_be_bytes()).unwrap(); - cur.write(&workchain_id.to_be_bytes()).unwrap(); - cur.write(&cc_seqno.to_be_bytes()).unwrap(); + cur.write_all(seed).unwrap(); + cur.write_all(&shard_pfx.to_be_bytes()).unwrap(); + cur.write_all(&workchain_id.to_be_bytes()).unwrap(); + cur.write_all(&cc_seqno.to_be_bytes()).unwrap(); ValidatorSetPRNG{ context,