From dfa90da51a9b11b91d9d4ca472f1b578667111d5 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 11 Mar 2025 14:18:19 +0100 Subject: [PATCH] Update to nom v8 --- Cargo.lock | 11 +- lib/Cargo.toml | 2 +- lib/src/author/runtime.rs | 288 ++++++------ lib/src/chain/chain_information/build.rs | 118 ++--- lib/src/chain_spec/light_sync_state.rs | 463 +++++++++++--------- lib/src/executor/host.rs | 95 ++-- lib/src/executor/host/runtime_version.rs | 144 +++--- lib/src/finality/decode.rs | 90 ++-- lib/src/header/grandpa.rs | 71 +-- lib/src/identity/keystore.rs | 71 ++- lib/src/identity/seed_phrase.rs | 8 +- lib/src/json_rpc/payment_info.rs | 33 +- lib/src/libp2p/connection/noise.rs | 73 ++- lib/src/libp2p/connection/webrtc_framing.rs | 17 +- lib/src/libp2p/connection/yamux/header.rs | 187 ++++---- lib/src/libp2p/multiaddr.rs | 171 +++++--- lib/src/libp2p/multihash.rs | 20 +- lib/src/libp2p/peer_id.rs | 9 +- lib/src/network/codec.rs | 119 ++--- lib/src/network/codec/block_announces.rs | 40 +- lib/src/network/codec/block_request.rs | 52 ++- lib/src/network/codec/grandpa.rs | 134 +++--- lib/src/network/codec/grandpa_warp_sync.rs | 37 +- lib/src/network/codec/identify.rs | 4 +- lib/src/network/codec/kademlia.rs | 4 +- lib/src/network/codec/state_request.rs | 4 +- lib/src/network/codec/storage_call_proof.rs | 4 +- lib/src/sync/para.rs | 15 +- lib/src/transactions/validate.rs | 256 ++++++----- lib/src/trie.rs | 10 +- lib/src/trie/proof_decode.rs | 13 +- lib/src/util.rs | 37 +- lib/src/util/protobuf.rs | 133 ++++-- lib/src/verify/body_only.rs | 11 +- wasm-node/rust/Cargo.toml | 2 +- wasm-node/rust/src/platform.rs | 15 +- 36 files changed, 1550 insertions(+), 1211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 495cf4c18b..2e2bea6376 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1637,12 +1637,6 @@ dependencies = [ "thrift", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.5" @@ -1678,12 +1672,11 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nom" -version = "7.1.3" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" dependencies = [ "memchr", - "minimal-lexical", ] [[package]] diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 0c40a94fb3..01137863a0 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -58,7 +58,7 @@ libm = { version = "0.2.8", default-features = false } libsecp256k1 = { version = "0.7.1", default-features = false, features = ["static-context", "hmac"] } # The log` crate is forbidden, as it is very impolite to emit logs from a library. merlin = { version = "3.0", default-features = false } -nom = { version = "7.1.3", default-features = false, features = ["alloc"] } +nom = { version = "8.0.0", default-features = false, features = ["alloc"] } num-bigint = { version = "0.4.3", default-features = false } num-rational = { version = "0.4.1", default-features = false, features = ["num-bigint"] } num-traits = { version = "0.2.19", default-features = false } diff --git a/lib/src/author/runtime.rs b/lib/src/author/runtime.rs index 88b8f7ebcd..316d3fbf3d 100644 --- a/lib/src/author/runtime.rs +++ b/lib/src/author/runtime.rs @@ -752,22 +752,25 @@ impl OffchainStorageSet { // containing its remaining size; this length prefix is fully part of the `Extrinsic` though. // In other words, this function might succeed or fail depending on the Substrate chain. fn parse_inherent_extrinsics_output(output: &[u8]) -> Result>, Error> { - nom::combinator::all_consuming(nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::combinator::map( - nom::combinator::recognize(nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - nom::bytes::streaming::take, - )), - |v: &[u8]| v.to_vec(), - ), - ) - }, - ))(output) + nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + nom::combinator::map( + nom::combinator::recognize(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + nom::bytes::streaming::take, + )), + |v: &[u8]| v.to_vec(), + ), + ) + }, + )), + output, + ) .map(|(_, parse_result)| parse_result) .map_err(|_: nom::Err<(&[u8], nom::error::ErrorKind)>| Error::BadInherentExtrinsicsOutput) } @@ -776,9 +779,12 @@ fn parse_inherent_extrinsics_output(output: &[u8]) -> Result>, Error fn parse_apply_extrinsic_output( output: &[u8], ) -> Result, TransactionValidityError>, Error> { - nom::combinator::all_consuming(apply_extrinsic_result)(output) - .map(|(_, parse_result)| parse_result) - .map_err(|_: nom::Err>| Error::BadApplyExtrinsicOutput) + nom::Parser::parse( + &mut nom::combinator::all_consuming(apply_extrinsic_result), + output, + ) + .map(|(_, parse_result)| parse_result) + .map_err(|_: nom::Err>| Error::BadApplyExtrinsicOutput) } // TODO: some parsers below are common with the tx-pool ; figure out how/whether they should be merged @@ -866,133 +872,157 @@ pub enum DispatchError { fn apply_extrinsic_result( bytes: &[u8], ) -> nom::IResult<&[u8], Result, TransactionValidityError>> { - nom::error::context( - "apply extrinsic result", - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), dispatch_outcome), - Ok, - ), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), - transaction_validity_error, + nom::Parser::parse( + &mut nom::error::context( + "apply extrinsic result", + nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded(nom::bytes::streaming::tag(&[0][..]), dispatch_outcome), + Ok, ), - Err, - ), - )), - )(bytes) + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[1][..]), + transaction_validity_error, + ), + Err, + ), + )), + ), + bytes, + ) } fn dispatch_outcome(bytes: &[u8]) -> nom::IResult<&[u8], Result<(), DispatchError>> { - nom::error::context( - "dispatch outcome", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| Ok(())), - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), dispatch_error), - Err, - ), - )), - )(bytes) + nom::Parser::parse( + &mut nom::error::context( + "dispatch outcome", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| Ok(())), + nom::combinator::map( + nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), dispatch_error), + Err, + ), + )), + ), + bytes, + ) } fn dispatch_error(bytes: &[u8]) -> nom::IResult<&[u8], DispatchError> { - nom::error::context( - "dispatch error", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - DispatchError::CannotLookup - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - DispatchError::BadOrigin - }), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), - nom::sequence::tuple((nom::number::streaming::u8, nom::number::streaming::u8)), + nom::Parser::parse( + &mut nom::error::context( + "dispatch error", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + DispatchError::CannotLookup + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + DispatchError::BadOrigin + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[2][..]), + (nom::number::streaming::u8, nom::number::streaming::u8), + ), + |(index, error)| DispatchError::Module { index, error }, ), - |(index, error)| DispatchError::Module { index, error }, - ), - )), - )(bytes) + )), + ), + bytes, + ) } fn transaction_validity_error(bytes: &[u8]) -> nom::IResult<&[u8], TransactionValidityError> { - nom::error::context( - "transaction validity error", - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), invalid_transaction), - TransactionValidityError::Invalid, - ), - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), unknown_transaction), - TransactionValidityError::Unknown, - ), - )), - )(bytes) + nom::Parser::parse( + &mut nom::error::context( + "transaction validity error", + nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + invalid_transaction, + ), + TransactionValidityError::Invalid, + ), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[1][..]), + unknown_transaction, + ), + TransactionValidityError::Unknown, + ), + )), + ), + bytes, + ) } fn invalid_transaction(bytes: &[u8]) -> nom::IResult<&[u8], InvalidTransaction> { - nom::error::context( - "invalid transaction", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - InvalidTransaction::Call - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - InvalidTransaction::Payment - }), - nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| { - InvalidTransaction::Future - }), - nom::combinator::map(nom::bytes::streaming::tag(&[3]), |_| { - InvalidTransaction::Stale - }), - nom::combinator::map(nom::bytes::streaming::tag(&[4]), |_| { - InvalidTransaction::BadProof - }), - nom::combinator::map(nom::bytes::streaming::tag(&[5]), |_| { - InvalidTransaction::AncientBirthBlock - }), - nom::combinator::map(nom::bytes::streaming::tag(&[6]), |_| { - InvalidTransaction::ExhaustsResources - }), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[7]), - nom::bytes::streaming::take(1u32), + nom::Parser::parse( + &mut nom::error::context( + "invalid transaction", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + InvalidTransaction::Call + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + InvalidTransaction::Payment + }), + nom::combinator::map(nom::bytes::streaming::tag(&[2][..]), |_| { + InvalidTransaction::Future + }), + nom::combinator::map(nom::bytes::streaming::tag(&[3][..]), |_| { + InvalidTransaction::Stale + }), + nom::combinator::map(nom::bytes::streaming::tag(&[4][..]), |_| { + InvalidTransaction::BadProof + }), + nom::combinator::map(nom::bytes::streaming::tag(&[5][..]), |_| { + InvalidTransaction::AncientBirthBlock + }), + nom::combinator::map(nom::bytes::streaming::tag(&[6][..]), |_| { + InvalidTransaction::ExhaustsResources + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[7][..]), + nom::bytes::streaming::take(1u32), + ), + |n: &[u8]| InvalidTransaction::Custom(n[0]), ), - |n: &[u8]| InvalidTransaction::Custom(n[0]), - ), - nom::combinator::map(nom::bytes::streaming::tag(&[8]), |_| { - InvalidTransaction::BadMandatory - }), - nom::combinator::map(nom::bytes::streaming::tag(&[9]), |_| { - InvalidTransaction::MandatoryDispatch - }), - )), - )(bytes) + nom::combinator::map(nom::bytes::streaming::tag(&[8][..]), |_| { + InvalidTransaction::BadMandatory + }), + nom::combinator::map(nom::bytes::streaming::tag(&[9][..]), |_| { + InvalidTransaction::MandatoryDispatch + }), + )), + ), + bytes, + ) } fn unknown_transaction(bytes: &[u8]) -> nom::IResult<&[u8], UnknownTransaction> { - nom::error::context( - "unknown transaction", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - UnknownTransaction::CannotLookup - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - UnknownTransaction::NoUnsignedValidator - }), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), - nom::bytes::streaming::take(1u32), + nom::Parser::parse( + &mut nom::error::context( + "unknown transaction", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + UnknownTransaction::CannotLookup + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + UnknownTransaction::NoUnsignedValidator + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[2][..]), + nom::bytes::streaming::take(1u32), + ), + |n: &[u8]| UnknownTransaction::Custom(n[0]), ), - |n: &[u8]| UnknownTransaction::Custom(n[0]), - ), - )), - )(bytes) + )), + ), + bytes, + ) } diff --git a/lib/src/chain/chain_information/build.rs b/lib/src/chain/chain_information/build.rs index 8baee624cf..994a5c71cf 100644 --- a/lib/src/chain/chain_information/build.rs +++ b/lib/src/chain/chain_information/build.rs @@ -930,9 +930,9 @@ fn decode_babe_configuration_output( bytes: &[u8], is_babe_api_v1: bool, ) -> Result { - let result: nom::IResult<_, _> = - nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( - nom::sequence::tuple(( + let result: nom::IResult<_, _> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( + ( nom::number::streaming::le_u64, nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), nom::number::streaming::le_u64, @@ -942,10 +942,10 @@ fn decode_babe_configuration_output( num_elems, num_elems, nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), nom::number::streaming::le_u64, - )), + ), move |(public_key, weight)| header::BabeAuthority { public_key: <[u8; 32]>::try_from(public_key).unwrap(), weight, @@ -958,29 +958,35 @@ fn decode_babe_configuration_output( }), |b| { if is_babe_api_v1 { - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - header::BabeAllowedSlots::PrimarySlots - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots - }), - ))(b) + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + header::BabeAllowedSlots::PrimarySlots + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots + }), + )), + b, + ) } else { - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - header::BabeAllowedSlots::PrimarySlots - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots - }), - nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| { - header::BabeAllowedSlots::PrimaryAndSecondaryVrfSlots - }), - ))(b) + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + header::BabeAllowedSlots::PrimarySlots + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots + }), + nom::combinator::map(nom::bytes::streaming::tag(&[2][..]), |_| { + header::BabeAllowedSlots::PrimaryAndSecondaryVrfSlots + }), + )), + b, + ) } }, - )), + ), |(_slot_duration, slots_per_epoch, c0, c1, authorities, randomness, allowed_slots)| { // Note that the slot duration is unused as it is not modifiable anyway. BabeGenesisConfiguration { @@ -995,7 +1001,9 @@ fn decode_babe_configuration_output( }, } }, - )))(bytes); + ))), + bytes, + ); match result { Ok((_, out)) => Ok(out), @@ -1011,7 +1019,7 @@ fn decode_babe_epoch_output( is_next_epoch: bool, ) -> Result { let mut combinator = nom::combinator::all_consuming(nom::combinator::map( - nom::sequence::tuple(( + ( nom::number::streaming::le_u64, nom::number::streaming::le_u64, nom::number::streaming::le_u64, @@ -1020,10 +1028,10 @@ fn decode_babe_epoch_output( num_elems, num_elems, nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), nom::number::streaming::le_u64, - )), + ), move |(public_key, weight)| header::BabeAuthority { public_key: <[u8; 32]>::try_from(public_key).unwrap(), weight, @@ -1043,7 +1051,7 @@ fn decode_babe_epoch_output( nom::Err::Error(nom::error::make_error(b, nom::error::ErrorKind::Verify)) }) }, - )), + ), |( epoch_index, start_slot_number, @@ -1073,7 +1081,8 @@ fn decode_babe_epoch_output( }, )); - let result: Result<_, nom::Err>> = combinator(scale_encoded); + let result: Result<_, nom::Err>> = + nom::Parser::parse(&mut combinator, scale_encoded); match result { Ok((_, info)) => Ok(info), Err(_) => Err(if is_next_epoch { @@ -1089,26 +1098,33 @@ fn decode_babe_epoch_output( fn decode_grandpa_authorities_output( scale_encoded: &[u8], ) -> Result, Error> { - let result: nom::IResult<_, _> = nom::combinator::all_consuming(nom::combinator::complete( - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { - nom::multi::fold_many_m_n( - num_elems, - num_elems, - nom::sequence::tuple(( - nom::bytes::streaming::take(32u32), - nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), - )), - move || Vec::with_capacity(num_elems), - |mut acc, (public_key, weight)| { - acc.push(header::GrandpaAuthority { - public_key: <[u8; 32]>::try_from(public_key).unwrap(), - weight, - }); - acc - }, - ) - }), - ))(scale_encoded); + let result: nom::IResult<_, _> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + |num_elems| { + nom::multi::fold_many_m_n( + num_elems, + num_elems, + ( + nom::bytes::streaming::take(32u32), + nom::combinator::map_opt( + nom::number::streaming::le_u64, + NonZero::::new, + ), + ), + move || Vec::with_capacity(num_elems), + |mut acc, (public_key, weight)| { + acc.push(header::GrandpaAuthority { + public_key: <[u8; 32]>::try_from(public_key).unwrap(), + weight, + }); + acc + }, + ) + }, + ))), + scale_encoded, + ); match result { Ok((_, out)) => Ok(out), diff --git a/lib/src/chain_spec/light_sync_state.rs b/lib/src/chain_spec/light_sync_state.rs index bf3b552688..eeae25cee3 100644 --- a/lib/src/chain_spec/light_sync_state.rs +++ b/lib/src/chain_spec/light_sync_state.rs @@ -40,18 +40,17 @@ impl LightSyncState { // in Substrate to these data structures. // This really should be solved by having a proper format for checkpoints, but // there isn't. - let grandpa_authority_set = match nom::Finish::finish(nom::combinator::complete( - authority_set::>, - )( - &self.grandpa_authority_set.0[..] + let grandpa_authority_set = match nom::Finish::finish(nom::Parser::parse( + &mut nom::combinator::complete(authority_set::>), + &self.grandpa_authority_set.0[..], )) { Ok((_, v)) => v, Err(_err) => return Err(ParseError(ParseErrorInner::Other)), }; - let babe_epoch_changes = match nom::Finish::finish(nom::combinator::complete( - epoch_changes::>, - )(&self.babe_epoch_changes.0[..])) - { + let babe_epoch_changes = match nom::Finish::finish(nom::Parser::parse( + &mut nom::combinator::complete(epoch_changes::>), + &self.babe_epoch_changes.0[..], + )) { Ok((_, v)) => v, Err(_err) => return Err(ParseError(ParseErrorInner::Other)), }; @@ -89,29 +88,32 @@ pub(super) struct EpochChanges { fn epoch_changes<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], EpochChanges, E> { - nom::combinator::map( - nom::sequence::tuple(( - fork_tree(persisted_epoch_header), - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::sequence::tuple(( - nom::bytes::streaming::take(32u32), - nom::number::streaming::le_u32, - persisted_epoch, - )), - ) - }), - )), - move |(inner, epochs)| EpochChanges { - _inner: inner, - epochs: epochs - .into_iter() - .map(|(h, n, e)| ((*<&[u8; 32]>::try_from(h).unwrap(), n), e)) - .collect(), - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + fork_tree(&mut persisted_epoch_header), + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + ( + nom::bytes::streaming::take(32u32), + nom::number::streaming::le_u32, + persisted_epoch, + ), + ) + }), + ), + move |(inner, epochs)| EpochChanges { + _inner: inner, + epochs: epochs + .into_iter() + .map(|(h, n, e)| ((*<&[u8; 32]>::try_from(h).unwrap(), n), e)) + .collect(), + }, + ), + bytes, + ) } #[allow(unused)] @@ -125,25 +127,28 @@ pub(super) struct GapEpochs { fn gap_epochs<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], GapEpochs, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::sequence::tuple(( - nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { - *<&[u8; 32]>::try_from(b).unwrap() - }), - nom::number::streaming::le_u32, - persisted_epoch, - )), - crate::util::nom_option_decode(nom::sequence::tuple(( - nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { - *<&[u8; 32]>::try_from(b).unwrap() - }), - nom::number::streaming::le_u32, - babe_epoch, - ))), - )), - move |(current, next)| GapEpochs { current, next }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + ( + nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { + *<&[u8; 32]>::try_from(b).unwrap() + }), + nom::number::streaming::le_u32, + persisted_epoch, + ), + crate::util::nom_option_decode(( + nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { + *<&[u8; 32]>::try_from(b).unwrap() + }), + nom::number::streaming::le_u32, + babe_epoch, + )), + ), + move |(current, next)| GapEpochs { current, next }, + ), + bytes, + ) } #[derive(Debug)] @@ -156,19 +161,22 @@ pub(super) enum PersistedEpochHeader { fn persisted_epoch_header<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], PersistedEpochHeader, E> { - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), - nom::sequence::tuple((epoch_header, epoch_header)), + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + (epoch_header, epoch_header), + ), + |(a, b)| PersistedEpochHeader::Genesis(a, b), ), - |(a, b)| PersistedEpochHeader::Genesis(a, b), - ), - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), epoch_header), - PersistedEpochHeader::Regular, - ), - ))(bytes) + nom::combinator::map( + nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), epoch_header), + PersistedEpochHeader::Regular, + ), + )), + bytes, + ) } #[derive(Debug)] @@ -180,16 +188,19 @@ pub(super) struct EpochHeader { fn epoch_header<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], EpochHeader, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::number::streaming::le_u64, - nom::number::streaming::le_u64, - )), - move |(start_slot, end_slot)| EpochHeader { - _start_slot: start_slot, - _end_slot: end_slot, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::number::streaming::le_u64, + nom::number::streaming::le_u64, + ), + move |(start_slot, end_slot)| EpochHeader { + _start_slot: start_slot, + _end_slot: end_slot, + }, + ), + bytes, + ) } #[derive(Debug)] @@ -202,19 +213,22 @@ pub(super) enum PersistedEpoch { fn persisted_epoch<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], PersistedEpoch, E> { - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), - nom::sequence::tuple((babe_epoch, babe_epoch)), + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + (babe_epoch, babe_epoch), + ), + |(a, b)| PersistedEpoch::Genesis(a, b), ), - |(a, b)| PersistedEpoch::Genesis(a, b), - ), - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), babe_epoch), - PersistedEpoch::Regular, - ), - ))(bytes) + nom::combinator::map( + nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), babe_epoch), + PersistedEpoch::Regular, + ), + )), + bytes, + ) } #[derive(Debug)] @@ -230,32 +244,40 @@ pub(super) struct BabeEpoch { fn babe_epoch<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], BabeEpoch, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::number::streaming::le_u64, - nom::number::streaming::le_u64, - nom::number::streaming::le_u64, - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n(num_elems, num_elems, babe_authority) - }), - nom::bytes::streaming::take(32u32), - |b| { - BabeNextConfig::from_slice(b) - .map(|c| (&b[17..], c)) // TODO: hacky to use a constant - .map_err(|_| { - nom::Err::Error(nom::error::make_error(b, nom::error::ErrorKind::MapOpt)) - }) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::number::streaming::le_u64, + nom::number::streaming::le_u64, + nom::number::streaming::le_u64, + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n(num_elems, num_elems, babe_authority) + }), + nom::bytes::streaming::take(32u32), + |b| { + BabeNextConfig::from_slice(b) + .map(|c| (&b[17..], c)) // TODO: hacky to use a constant + .map_err(|_| { + nom::Err::Error(nom::error::make_error( + b, + nom::error::ErrorKind::MapOpt, + )) + }) + }, + ), + move |(epoch_index, slot_number, duration, authorities, randomness, config)| { + BabeEpoch { + epoch_index, + slot_number, + duration, + authorities, + randomness: *<&[u8; 32]>::try_from(randomness).unwrap(), + config, + } }, - )), - move |(epoch_index, slot_number, duration, authorities, randomness, config)| BabeEpoch { - epoch_index, - slot_number, - duration, - authorities, - randomness: *<&[u8; 32]>::try_from(randomness).unwrap(), - config, - }, - )(bytes) + ), + bytes, + ) } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -272,16 +294,19 @@ pub struct BabeAuthority { fn babe_authority<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], BabeAuthority, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::take(32u32), - nom::number::streaming::le_u64, - )), - move |(public_key, weight)| BabeAuthority { - public_key: *<&[u8; 32]>::try_from(public_key).unwrap(), - weight, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::bytes::streaming::take(32u32), + nom::number::streaming::le_u64, + ), + move |(public_key, weight)| BabeAuthority { + public_key: *<&[u8; 32]>::try_from(public_key).unwrap(), + weight, + }, + ), + bytes, + ) } #[derive(Debug)] @@ -298,41 +323,44 @@ pub(super) struct AuthoritySet { fn authority_set<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], AuthoritySet, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n(num_elems, num_elems, grandpa_authority) - }), - nom::number::streaming::le_u64, - fork_tree(pending_change), - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n(num_elems, num_elems, pending_change) - }), - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::sequence::tuple(( - nom::number::streaming::le_u64, - nom::number::streaming::le_u32, - )), - ) - }), - )), - move |( - current_authorities, - set_id, - pending_standard_changes, - pending_forced_changes, - authority_set_changes, - )| AuthoritySet { - current_authorities, - set_id, - _pending_standard_changes: pending_standard_changes, - _pending_forced_changes: pending_forced_changes, - _authority_set_changes: authority_set_changes, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n(num_elems, num_elems, grandpa_authority) + }), + nom::number::streaming::le_u64, + fork_tree(&mut pending_change), + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n(num_elems, num_elems, pending_change) + }), + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + ( + nom::number::streaming::le_u64, + nom::number::streaming::le_u32, + ), + ) + }), + ), + move |( + current_authorities, + set_id, + pending_standard_changes, + pending_forced_changes, + authority_set_changes, + )| AuthoritySet { + current_authorities, + set_id, + _pending_standard_changes: pending_standard_changes, + _pending_forced_changes: pending_forced_changes, + _authority_set_changes: authority_set_changes, + }, + ), + bytes, + ) } #[derive(Debug)] @@ -347,24 +375,27 @@ pub(super) struct PendingChange { fn pending_change<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], PendingChange, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { - nom::multi::many_m_n(num_elems, num_elems, grandpa_authority) - }), - nom::number::streaming::le_u32, - nom::number::streaming::le_u32, - nom::bytes::streaming::take(32u32), - delay_kind, - )), - move |(next_authorities, delay, canon_height, canon_hash, delay_kind)| PendingChange { - _next_authorities: next_authorities, - _delay: delay, - _canon_height: canon_height, - _canon_hash: *<&[u8; 32]>::try_from(canon_hash).unwrap(), - _delay_kind: delay_kind, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { + nom::multi::many_m_n(num_elems, num_elems, grandpa_authority) + }), + nom::number::streaming::le_u32, + nom::number::streaming::le_u32, + nom::bytes::streaming::take(32u32), + delay_kind, + ), + move |(next_authorities, delay, canon_height, canon_hash, delay_kind)| PendingChange { + _next_authorities: next_authorities, + _delay: delay, + _canon_height: canon_height, + _canon_hash: *<&[u8; 32]>::try_from(canon_hash).unwrap(), + _delay_kind: delay_kind, + }, + ), + bytes, + ) } #[derive(Debug)] @@ -376,18 +407,23 @@ pub(super) enum DelayKind { fn delay_kind<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], DelayKind, E> { - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| DelayKind::Finalized), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), - nom::number::streaming::le_u32, + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + DelayKind::Finalized + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[1][..]), + nom::number::streaming::le_u32, + ), + |median_last_finalized| DelayKind::Best { + _median_last_finalized: median_last_finalized, + }, ), - |median_last_finalized| DelayKind::Best { - _median_last_finalized: median_last_finalized, - }, - ), - ))(bytes) + )), + bytes, + ) } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -405,16 +441,19 @@ pub struct GrandpaAuthority { fn grandpa_authority<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], GrandpaAuthority, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::take(32u32), - nom::number::streaming::le_u64, - )), - move |(public_key, weight)| GrandpaAuthority { - public_key: *<&[u8; 32]>::try_from(public_key).unwrap(), - weight, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::bytes::streaming::take(32u32), + nom::number::streaming::le_u64, + ), + move |(public_key, weight)| GrandpaAuthority { + public_key: *<&[u8; 32]>::try_from(public_key).unwrap(), + weight, + }, + ), + bytes, + ) } #[derive(Debug)] @@ -424,10 +463,10 @@ pub(super) struct ForkTree { } fn fork_tree<'a, T, E: nom::error::ParseError<&'a [u8]>>( - mut inner: impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], T, E>, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], ForkTree, E> { + inner: &mut impl nom::Parser<&'a [u8], Output = T, Error = E>, +) -> impl nom::Parser<&'a [u8], Output = ForkTree, Error = E> { nom::combinator::map( - nom::sequence::tuple(( + ( // We do parsing manually due to borrow checking troubles regarding `inner`. move |mut bytes| { let (bytes_rest, num_roots) = match crate::util::nom_scale_compact_usize(bytes) { @@ -438,10 +477,11 @@ fn fork_tree<'a, T, E: nom::error::ParseError<&'a [u8]>>( let mut roots = Vec::with_capacity(num_roots); for _ in 0..num_roots { - let (bytes_rest, child) = match fork_tree_node(&mut inner)(bytes) { - Ok(d) => d, - Err(err) => return Err(err), - }; + let (bytes_rest, child) = + match nom::Parser::parse(&mut fork_tree_node(inner), bytes) { + Ok(d) => d, + Err(err) => return Err(err), + }; bytes = bytes_rest; roots.push(child); } @@ -449,7 +489,7 @@ fn fork_tree<'a, T, E: nom::error::ParseError<&'a [u8]>>( Ok((bytes, roots)) }, crate::util::nom_option_decode(nom::number::streaming::le_u32), - )), + ), |(roots, best_finalized_number)| ForkTree { _roots: roots, _best_finalized_number: best_finalized_number, @@ -465,16 +505,16 @@ pub(super) struct ForkTreeNode { _children: Vec, } -fn fork_tree_node<'a, 'p, T, E: nom::error::ParseError<&'a [u8]>>( - inner: &'p mut dyn FnMut(&'a [u8]) -> nom::IResult<&'a [u8], T, E>, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], ForkTreeNode, E> + 'p { +fn fork_tree_node<'a, T, E: nom::error::ParseError<&'a [u8]>>( + inner: &mut impl nom::Parser<&'a [u8], Output = T, Error = E>, +) -> impl nom::Parser<&'a [u8], Output = ForkTreeNode, Error = E> { nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), nom::number::streaming::le_u32, // We do parsing manually due to borrow checking troubles regarding `inner`. move |mut bytes| { - let (bytes_rest, data) = match inner(bytes) { + let (bytes_rest, data) = match nom::Parser::parse(inner, bytes) { Ok(d) => d, Err(err) => return Err(err), }; @@ -488,17 +528,18 @@ fn fork_tree_node<'a, 'p, T, E: nom::error::ParseError<&'a [u8]>>( let mut children = Vec::with_capacity(num_children); for _ in 0..num_children { - let (bytes_rest, child) = match fork_tree_node(&mut *inner)(bytes) { - Ok(d) => d, - Err(err) => return Err(err), - }; + let (bytes_rest, child) = + match nom::Parser::parse(&mut fork_tree_node(inner), bytes) { + Ok(d) => d, + Err(err) => return Err(err), + }; bytes = bytes_rest; children.push(child); } Ok((bytes, (data, children))) }, - )), + ), |(hash, number, (data, children))| ForkTreeNode { _hash: *<&[u8; 32]>::try_from(hash).unwrap(), _number: number, diff --git a/lib/src/executor/host.rs b/lib/src/executor/host.rs index ee2bb9b72e..1124159cb9 100644 --- a/lib/src/executor/host.rs +++ b/lib/src/executor/host.rs @@ -1107,9 +1107,12 @@ impl ReadyToRun { let max_keys_to_remove = { let input = expect_pointer_size!(1); let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> = - nom::combinator::all_consuming(util::nom_option_decode( - nom::number::streaming::le_u32, - ))(input.as_ref()) + nom::Parser::parse( + &mut nom::combinator::all_consuming(util::nom_option_decode( + nom::number::streaming::le_u32, + )), + input.as_ref(), + ) .map(|(_, parse_result)| parse_result); match parsing_result { @@ -1309,9 +1312,12 @@ impl ReadyToRun { let max_keys_to_remove = { let input = expect_pointer_size!(1); let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> = - nom::combinator::all_consuming(util::nom_option_decode( - nom::number::streaming::le_u32, - ))(input.as_ref()) + nom::Parser::parse( + &mut nom::combinator::all_consuming(util::nom_option_decode( + nom::number::streaming::le_u32, + )), + input.as_ref(), + ) .map(|(_, parse_result)| parse_result); match parsing_result { @@ -1356,9 +1362,12 @@ impl ReadyToRun { let max_keys_to_remove = { let input = expect_pointer_size!(2); let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> = - nom::combinator::all_consuming(util::nom_option_decode( - nom::number::streaming::le_u32, - ))(input.as_ref()) + nom::Parser::parse( + &mut nom::combinator::all_consuming(util::nom_option_decode( + nom::number::streaming::le_u32, + )), + input.as_ref(), + ) .map(|(_, parse_result)| parse_result); match parsing_result { @@ -1984,25 +1993,28 @@ impl ReadyToRun { let result = { let input = expect_pointer_size!(0); let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> = - nom::combinator::all_consuming(nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::sequence::tuple(( - nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - nom::bytes::streaming::take, - ), - nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - nom::bytes::streaming::take, + nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + ( + nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + nom::bytes::streaming::take, + ), + nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + nom::bytes::streaming::take, + ), ), - )), - ) - }, - ))(input.as_ref()) + ) + }, + )), + input.as_ref(), + ) .map(|(_, parse_result)| parse_result); match parsing_result { @@ -2050,19 +2062,22 @@ impl ReadyToRun { let result = { let input = expect_pointer_size!(0); let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> = - nom::combinator::all_consuming(nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - nom::bytes::streaming::take, - ), - ) - }, - ))(input.as_ref()) + nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + nom::bytes::streaming::take, + ), + ) + }, + )), + input.as_ref(), + ) .map(|(_, parse_result)| parse_result); match parsing_result { diff --git a/lib/src/executor/host/runtime_version.rs b/lib/src/executor/host/runtime_version.rs index 5e3a39a967..fbbc7c7ed5 100644 --- a/lib/src/executor/host/runtime_version.rs +++ b/lib/src/executor/host/runtime_version.rs @@ -93,10 +93,10 @@ pub fn find_encoded_embedded_runtime_version_apis( ) -> Result { let mut parser = nom::combinator::all_consuming(nom::combinator::complete(nom::sequence::preceded( - nom::sequence::tuple(( - nom::bytes::streaming::tag(b"\0asm"), - nom::bytes::streaming::tag(&[0x1, 0x0, 0x0, 0x0]), - )), + ( + nom::bytes::streaming::tag(&b"\0asm"[..]), + nom::bytes::streaming::tag(&[0x1, 0x0, 0x0, 0x0][..]), + ), nom::multi::fold_many0( nom::combinator::complete(wasm_section), || (None, None), @@ -147,10 +147,11 @@ pub fn find_encoded_embedded_runtime_version_apis( ), ))); - let (runtime_version_content, runtime_apis_content) = match parser(binary_wasm_module) { - Ok((_, content)) => content, - Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse), - }; + let (runtime_version_content, runtime_apis_content) = + match nom::Parser::parse(&mut parser, binary_wasm_module) { + Ok((_, content)) => content, + Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse), + }; Ok(EmbeddedRuntimeVersionApis { runtime_version_content, @@ -295,15 +296,17 @@ impl<'a> CoreVersionApisRefIter<'a> { /// /// The input slice isn't expected to contain the number of APIs. pub fn from_slice_no_length(input: &'a [u8]) -> Result { - let result: Result<_, nom::Err>> = - nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( + let result: Result<_, nom::Err>> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( nom::combinator::recognize(nom::multi::fold_many0( nom::combinator::complete(core_version_api), || {}, |(), _| (), )), |inner| CoreVersionApisRefIter { inner }, - )))(input); + ))), + input, + ); match result { Ok((_, me)) => Ok(me), @@ -437,9 +440,9 @@ pub struct CoreVersionApi { fn decode(scale_encoded: &[u8]) -> Result { // See https://spec.polkadot.network/#defn-rt-core-version - let result: nom::IResult<_, _> = - nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( - nom::sequence::tuple(( + let result: nom::IResult<_, _> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( + ( crate::util::nom_string_decode, crate::util::nom_string_decode, nom::number::streaming::le_u32, @@ -455,16 +458,16 @@ fn decode(scale_encoded: &[u8]) -> Result { )), nom::branch::alt(( nom::combinator::complete(nom::combinator::map( - nom::bytes::streaming::tag(&[0]), + nom::bytes::streaming::tag(&[0][..]), |_| Some(TrieEntryVersion::V0), )), nom::combinator::complete(nom::combinator::map( - nom::bytes::streaming::tag(&[1]), + nom::bytes::streaming::tag(&[1][..]), |_| Some(TrieEntryVersion::V1), )), nom::combinator::map(nom::combinator::eof, |_| None), )), - )), + ), |( spec_name, impl_name, @@ -484,7 +487,9 @@ fn decode(scale_encoded: &[u8]) -> Result { transaction_version, state_version, }, - )))(scale_encoded); + ))), + scale_encoded, + ); match result { Ok((_, out)) => Ok(out), @@ -496,33 +501,39 @@ fn decode(scale_encoded: &[u8]) -> Result { fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], CoreVersionApisRefIter<'a>, E> { - nom::combinator::map( - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { - nom::combinator::recognize(nom::multi::fold_many_m_n( - num_elems, - num_elems, - core_version_api, - || {}, - |(), _| (), - )) - }), - |inner| CoreVersionApisRefIter { inner }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { + nom::combinator::recognize(nom::multi::fold_many_m_n( + num_elems, + num_elems, + core_version_api, + || {}, + |(), _| (), + )) + }), + |inner| CoreVersionApisRefIter { inner }, + ), + bytes, + ) } fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], CoreVersionApi, E> { - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::take(8u32), - nom::number::streaming::le_u32, - )), - move |(name, version)| CoreVersionApi { - name_hash: <[u8; 8]>::try_from(name).unwrap(), - version, - }, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + nom::bytes::streaming::take(8u32), + nom::number::streaming::le_u32, + ), + move |(name, version)| CoreVersionApi { + name_hash: <[u8; 8]>::try_from(name).unwrap(), + version, + }, + ), + bytes, + ) } struct WasmSection<'a> { @@ -532,35 +543,38 @@ struct WasmSection<'a> { /// Parses a Wasm section. If it is a custom section, returns its name and content. fn wasm_section(bytes: &[u8]) -> nom::IResult<&[u8], Option> { - nom::branch::alt(( - nom::combinator::map( - nom::combinator::map_parser( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), - nom::multi::length_data(nom::combinator::map_opt( - crate::util::leb128::nom_leb128_u64, - |n| u32::try_from(n).ok(), - )), + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map( + nom::combinator::map_parser( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + nom::multi::length_data(nom::combinator::map_opt( + crate::util::leb128::nom_leb128_u64, + |n| u32::try_from(n).ok(), + )), + ), + ( + nom::multi::length_data(nom::combinator::map_opt( + crate::util::leb128::nom_leb128_u64, + |n| u32::try_from(n).ok(), + )), + nom::combinator::rest, + ), ), - nom::sequence::tuple(( + |(name, content)| Some(WasmSection { name, content }), + ), + nom::combinator::map( + ( + nom::number::streaming::u8, nom::multi::length_data(nom::combinator::map_opt( crate::util::leb128::nom_leb128_u64, |n| u32::try_from(n).ok(), )), - nom::combinator::rest, - )), + ), + |_| None, ), - |(name, content)| Some(WasmSection { name, content }), - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::number::streaming::u8, - nom::multi::length_data(nom::combinator::map_opt( - crate::util::leb128::nom_leb128_u64, - |n| u32::try_from(n).ok(), - )), - )), - |_| None, - ), - ))(bytes) + )), + bytes, + ) } diff --git a/lib/src/finality/decode.rs b/lib/src/finality/decode.rs index 98ce227bce..c5eee1025f 100644 --- a/lib/src/finality/decode.rs +++ b/lib/src/finality/decode.rs @@ -25,10 +25,14 @@ pub fn decode_grandpa_justification( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result { - match nom::combinator::complete(nom::combinator::all_consuming(grandpa_justification( - block_number_bytes, - )))(scale_encoded) - { + match nom::Parser::parse( + &mut nom::combinator::complete(nom::combinator::all_consuming::< + _, + nom::error::Error<&[u8]>, + _, + >(grandpa_justification(block_number_bytes))), + scale_encoded, + ) { Ok((_, justification)) => Ok(justification), Err(nom::Err::Error(err) | nom::Err::Failure(err)) => { Err(JustificationDecodeError(err.code)) @@ -45,7 +49,12 @@ pub fn decode_partial_grandpa_justification( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result<(GrandpaJustificationRef, &[u8]), JustificationDecodeError> { - match nom::combinator::complete(grandpa_justification(block_number_bytes))(scale_encoded) { + match nom::Parser::parse( + &mut nom::combinator::complete(grandpa_justification::>( + block_number_bytes, + )), + scale_encoded, + ) { Ok((remainder, justification)) => Ok((justification, remainder)), Err(nom::Err::Error(err) | nom::Err::Failure(err)) => { Err(JustificationDecodeError(err.code)) @@ -81,7 +90,10 @@ pub fn decode_grandpa_commit( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result { - match nom::combinator::all_consuming(commit_message(block_number_bytes))(scale_encoded) { + match nom::Parser::parse( + &mut nom::combinator::all_consuming(commit_message(block_number_bytes)), + scale_encoded, + ) { Ok((_, commit)) => Ok(commit), Err(err) => Err(CommitDecodeError(err)), } @@ -95,7 +107,7 @@ pub fn decode_partial_grandpa_commit( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result<(CommitMessageRef, &[u8]), CommitDecodeError> { - match commit_message(block_number_bytes)(scale_encoded) { + match nom::Parser::parse(&mut commit_message(block_number_bytes), scale_encoded) { Ok((remainder, commit)) => Ok((commit, remainder)), Err(err) => Err(CommitDecodeError(err)), } @@ -231,7 +243,11 @@ impl<'a> Iterator for PrecommitsRefIter<'a> { return None; } - let (new_pointer, precommit) = precommit(*block_number_bytes)(pointer).unwrap(); + let (new_pointer, precommit) = nom::Parser::parse( + &mut precommit::>(*block_number_bytes), + pointer, + ) + .unwrap(); *pointer = new_pointer; *remaining_len -= 1; @@ -276,7 +292,10 @@ impl PrecommitRef<'_> { scale_encoded: &[u8], block_number_bytes: usize, ) -> Result<(PrecommitRef, &[u8]), JustificationDecodeError> { - match precommit(block_number_bytes)(scale_encoded) { + match nom::Parser::parse( + &mut precommit::>(block_number_bytes), + scale_encoded, + ) { Ok((remainder, precommit)) => Ok((precommit, remainder)), Err(nom::Err::Error(err) | nom::Err::Failure(err)) => { Err(JustificationDecodeError(err.code)) @@ -366,19 +385,22 @@ impl ExactSizeIterator for VotesAncestriesIter<'_> {} pub struct JustificationDecodeError(#[error(not(source))] nom::error::ErrorKind); /// `Nom` combinator that parses a justification. -fn grandpa_justification<'a>( +fn grandpa_justification< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], GrandpaJustificationRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = GrandpaJustificationRef<'a>, Error = E> { nom::error::context( "grandpa_justification", nom::combinator::map( - nom::sequence::tuple(( + ( nom::number::streaming::le_u64, nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), precommits(block_number_bytes), votes_ancestries(block_number_bytes), - )), + ), |(round, target_hash, target_number, precommits, votes_ancestries)| { GrandpaJustificationRef { round, @@ -393,9 +415,9 @@ fn grandpa_justification<'a>( } /// `Nom` combinator that parses a list of precommits. -fn precommits<'a>( +fn precommits<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], PrecommitsRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = PrecommitsRef<'a>, Error = E> { nom::combinator::map( nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { nom::combinator::recognize(nom::multi::fold_many_m_n( @@ -416,18 +438,18 @@ fn precommits<'a>( } /// `Nom` combinator that parses a single precommit. -fn precommit<'a>( +fn precommit<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], PrecommitRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = PrecommitRef<'a>, Error = E> { nom::error::context( "precommit", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), nom::bytes::streaming::take(64u32), nom::bytes::streaming::take(32u32), - )), + ), |(target_hash, target_number, signature, authority_public_key)| PrecommitRef { target_hash: TryFrom::try_from(target_hash).unwrap(), target_number, @@ -439,9 +461,12 @@ fn precommit<'a>( } /// `Nom` combinator that parses a list of headers. -fn votes_ancestries<'a>( +fn votes_ancestries< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], VotesAncestriesIter<'a>> { +) -> impl nom::Parser<&'a [u8], Output = VotesAncestriesIter<'a>, Error = E> { nom::error::context( "votes ancestries", nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { @@ -472,13 +497,13 @@ fn votes_ancestries<'a>( ) } -fn commit_message<'a>( +fn commit_message<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], CommitMessageRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = CommitMessageRef<'a>, Error = E> { nom::error::context( "commit_message", nom::combinator::map( - nom::sequence::tuple(( + ( nom::number::streaming::le_u64, nom::number::streaming::le_u64, nom::bytes::streaming::take(32u32), @@ -495,10 +520,10 @@ fn commit_message<'a>( num_elems, num_elems, nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(64u32), nom::bytes::streaming::take(32u32), - )), + ), |(sig, pubkey)| { ( <&[u8; 64]>::try_from(sig).unwrap(), @@ -508,7 +533,7 @@ fn commit_message<'a>( ), ) }), - )), + ), |(round_number, set_id, target_hash, target_number, precommits, auth_data)| { CommitMessageRef { round_number, @@ -523,16 +548,19 @@ fn commit_message<'a>( ) } -fn unsigned_precommit<'a>( +fn unsigned_precommit< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], UnsignedPrecommitRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = UnsignedPrecommitRef<'a>, Error = E> { nom::error::context( "unsigned_precommit", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(target_hash, target_number)| UnsignedPrecommitRef { target_hash: <&[u8; 32]>::try_from(target_hash).unwrap(), target_number, diff --git a/lib/src/header/grandpa.rs b/lib/src/header/grandpa.rs index e06829b64e..f4bf2d9f74 100644 --- a/lib/src/header/grandpa.rs +++ b/lib/src/header/grandpa.rs @@ -72,13 +72,14 @@ pub enum GrandpaConsensusLogRef<'a> { impl<'a> GrandpaConsensusLogRef<'a> { /// Decodes a [`GrandpaConsensusLogRef`] from a slice of bytes. pub fn from_slice(slice: &'a [u8], block_number_bytes: usize) -> Result { - Ok( - nom::combinator::all_consuming(grandpa_consensus_log_ref(block_number_bytes))(slice) - .map_err(|_: nom::Err<(&[u8], nom::error::ErrorKind)>| { - Error::GrandpaConsensusLogDecodeError - })? - .1, + Ok(nom::Parser::parse( + &mut nom::combinator::all_consuming(grandpa_consensus_log_ref(block_number_bytes)), + slice, ) + .map_err(|_: nom::Err<(&[u8], nom::error::ErrorKind)>| { + Error::GrandpaConsensusLogDecodeError + })? + .1) } /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE @@ -319,9 +320,12 @@ impl<'a> Iterator for GrandpaAuthoritiesIter<'a> { GrandpaAuthoritiesIterInner::Encoded(inner) => { let item = inner.next()?; Some( - nom::combinator::all_consuming::<_, _, (&[u8], nom::error::ErrorKind), _>( - grandpa_authority_ref, - )(item) + nom::Parser::parse( + &mut nom::combinator::all_consuming::<_, (&[u8], nom::error::ErrorKind), _>( + grandpa_authority_ref, + ), + item, + ) .unwrap() .1, ) @@ -425,24 +429,24 @@ fn grandpa_consensus_log_ref< E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>, >( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], GrandpaConsensusLogRef<'a>, E> { +) -> impl nom::Parser<&'a [u8], Output = GrandpaConsensusLogRef<'a>, Error = E> { nom::error::context( "grandpa_consensus_log_ref", nom::branch::alt(( nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), + nom::bytes::streaming::tag(&[1][..]), grandpa_scheduled_change_ref(block_number_bytes), ), GrandpaConsensusLogRef::ScheduledChange, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), - nom::sequence::tuple(( + nom::bytes::streaming::tag(&[2][..]), + ( crate::util::nom_varsize_number_decode_u64(block_number_bytes), grandpa_scheduled_change_ref(block_number_bytes), - )), + ), ), |(reset_block_height, change)| GrandpaConsensusLogRef::ForcedChange { reset_block_height, @@ -451,21 +455,21 @@ fn grandpa_consensus_log_ref< ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[3]), + nom::bytes::streaming::tag(&[3][..]), nom::number::streaming::le_u64, ), GrandpaConsensusLogRef::OnDisabled, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[4]), + nom::bytes::streaming::tag(&[4][..]), crate::util::nom_varsize_number_decode_u64(block_number_bytes), ), GrandpaConsensusLogRef::Pause, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[5]), + nom::bytes::streaming::tag(&[5][..]), crate::util::nom_varsize_number_decode_u64(block_number_bytes), ), GrandpaConsensusLogRef::Resume, @@ -479,11 +483,11 @@ fn grandpa_scheduled_change_ref< E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>, >( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], GrandpaScheduledChangeRef<'a>, E> { +) -> impl nom::Parser<&'a [u8], Output = GrandpaScheduledChangeRef<'a>, Error = E> { nom::error::context( "grandpa_scheduled_change_ref", nom::combinator::map( - nom::sequence::tuple(( + ( nom::combinator::flat_map(util::nom_scale_compact_usize, |num_authorities| { nom::combinator::map( nom::combinator::recognize(nom::multi::fold_many_m_n( @@ -501,7 +505,7 @@ fn grandpa_scheduled_change_ref< ) }), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(next_authorities, delay)| GrandpaScheduledChangeRef { next_authorities, delay, @@ -516,17 +520,20 @@ fn grandpa_authority_ref< >( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], GrandpaAuthorityRef<'a>, E> { - nom::error::context( - "grandpa_authority_ref", - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::take(32u32), - nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), - )), - |(public_key, weight)| GrandpaAuthorityRef { - public_key: TryFrom::try_from(public_key).unwrap(), - weight, - }, + nom::Parser::parse( + &mut nom::error::context( + "grandpa_authority_ref", + nom::combinator::map( + ( + nom::bytes::streaming::take(32u32), + nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), + ), + |(public_key, weight)| GrandpaAuthorityRef { + public_key: TryFrom::try_from(public_key).unwrap(), + weight, + }, + ), ), - )(bytes) + bytes, + ) } diff --git a/lib/src/identity/keystore.rs b/lib/src/identity/keystore.rs index 7f1db489a4..373643a22b 100644 --- a/lib/src/identity/keystore.rs +++ b/lib/src/identity/keystore.rs @@ -148,42 +148,41 @@ impl Keystore { Err(_) => continue, }; - let mut parser = - nom::combinator::all_consuming::<_, _, (&str, nom::error::ErrorKind), _>( - nom::combinator::complete(nom::sequence::tuple(( - nom::combinator::map_opt( - nom::bytes::streaming::take(4u32), - KeyNamespace::from_string, - ), - nom::bytes::streaming::tag("-"), - nom::combinator::map_opt( - nom::bytes::streaming::take(7u32), - |b| match b { - "ed25519" => Some(PrivateKey::FileEd25519), - "sr25519" => Some(PrivateKey::FileSr25519), - _ => None, - }, - ), - nom::bytes::streaming::tag("-"), - nom::combinator::map_opt( - nom::bytes::complete::take_while(|c: char| { - c.is_ascii_digit() || ('a'..='f').contains(&c) - }), - |k: &str| { - if k.len() == 64 { - Some(<[u8; 32]>::try_from(hex::decode(k).unwrap()).unwrap()) - } else { - None - } - }, - ), - ))), - ); - - let (namespace, _, algorithm, _, public_key) = match parser(&file_name) { - Ok((_, v)) => v, - Err(_) => continue, - }; + let mut parser = nom::combinator::all_consuming::< + _, + (&str, nom::error::ErrorKind), + _, + >(nom::combinator::complete(( + nom::combinator::map_opt( + nom::bytes::streaming::take(4u32), + KeyNamespace::from_string, + ), + nom::bytes::streaming::tag("-"), + nom::combinator::map_opt(nom::bytes::streaming::take(7u32), |b| match b { + "ed25519" => Some(PrivateKey::FileEd25519), + "sr25519" => Some(PrivateKey::FileSr25519), + _ => None, + }), + nom::bytes::streaming::tag("-"), + nom::combinator::map_opt( + nom::bytes::complete::take_while(|c: char| { + c.is_ascii_digit() || ('a'..='f').contains(&c) + }), + |k: &str| { + if k.len() == 64 { + Some(<[u8; 32]>::try_from(hex::decode(k).unwrap()).unwrap()) + } else { + None + } + }, + ), + ))); + + let (namespace, _, algorithm, _, public_key) = + match nom::Parser::parse(&mut parser, &file_name) { + Ok((_, v)) => v, + Err(_) => continue, + }; // Make sure that the content of the file is valid and that it corresponds to // the public key advertised in the file name. diff --git a/lib/src/identity/seed_phrase.rs b/lib/src/identity/seed_phrase.rs index 91d02566fc..11bbe55ffd 100644 --- a/lib/src/identity/seed_phrase.rs +++ b/lib/src/identity/seed_phrase.rs @@ -92,8 +92,8 @@ pub fn decode_ed25519_private_key(phrase: &str) -> Result, ParsePr /// Turns a human-readable private key (a.k.a. a seed phrase) into a seed and a derivation path. pub fn parse_private_key(phrase: &str) -> Result { - let parse_result: Result<_, nom::Err>> = - nom::combinator::all_consuming(nom::sequence::tuple(( + let parse_result: Result<_, nom::Err>> = nom::Parser::parse( + &mut nom::combinator::all_consuming(( // Either BIP39 words or some hexadecimal nom::branch::alt(( // Hexadecimal. Wrapped in `either::Left` @@ -141,7 +141,9 @@ pub fn parse_private_key(phrase: &str) -> Result { diff --git a/lib/src/json_rpc/payment_info.rs b/lib/src/json_rpc/payment_info.rs index a5f7a51043..9693c9bb22 100644 --- a/lib/src/json_rpc/payment_info.rs +++ b/lib/src/json_rpc/payment_info.rs @@ -43,10 +43,12 @@ pub fn decode_payment_info( _ => return Err(DecodeError::UnknownRuntimeVersion), }; - match nom::combinator::all_consuming(nom_decode_payment_info::>( - is_api_v2, - ))(scale_encoded) - { + match nom::Parser::parse( + &mut nom::combinator::all_consuming(nom_decode_payment_info::>( + is_api_v2, + )), + scale_encoded, + ) { Ok((_, info)) => Ok(info), Err(_) => Err(DecodeError::ParseError), } @@ -63,20 +65,23 @@ pub enum DecodeError { fn nom_decode_payment_info<'a, E: nom::error::ParseError<&'a [u8]>>( is_api_v2: bool, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], methods::RuntimeDispatchInfo, E> { +) -> impl nom::Parser<&'a [u8], Output = methods::RuntimeDispatchInfo, Error = E> { nom::combinator::map( - nom::sequence::tuple(( + ( move |bytes| { if is_api_v2 { nom::number::streaming::le_u64(bytes) } else { - nom::combinator::map( - nom::sequence::tuple(( - crate::util::nom_scale_compact_u64, - crate::util::nom_scale_compact_u64, - )), - |(ref_time, _proof_size)| ref_time, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map( + ( + crate::util::nom_scale_compact_u64, + crate::util::nom_scale_compact_u64, + ), + |(ref_time, _proof_size)| ref_time, + ), + bytes, + ) } }, nom::combinator::map_opt(nom::number::streaming::u8, |n| match n { @@ -123,7 +128,7 @@ fn nom_decode_payment_info<'a, E: nom::error::ParseError<&'a [u8]>>( Ok((&[][..], num)) }, - )), + ), |(weight, class, partial_fee)| methods::RuntimeDispatchInfo { weight, class, diff --git a/lib/src/libp2p/connection/noise.rs b/lib/src/libp2p/connection/noise.rs index 65377f05a3..5c995e4e96 100644 --- a/lib/src/libp2p/connection/noise.rs +++ b/lib/src/libp2p/connection/noise.rs @@ -868,16 +868,13 @@ impl HandshakeInProgress { self.0.remote_ephemeral_public_key = x25519_dalek::PublicKey::from(*{ // Because the remote hasn't authenticated us at this point, sending more // data than what the protocol specifies is forbidden. - let mut parser = nom::combinator::all_consuming::< - _, - _, - (&[u8], nom::error::ErrorKind), - _, - >(nom::combinator::map( - nom::bytes::streaming::take(32u32), - |k| <&[u8; 32]>::try_from(k).unwrap(), - )); - match parser(&available_message) { + let mut parser = + nom::combinator::all_consuming::<_, (&[u8], nom::error::ErrorKind), _>( + nom::combinator::map(nom::bytes::streaming::take(32u32), |k| { + <&[u8; 32]>::try_from(k).unwrap() + }), + ); + match nom::Parser::parse(&mut parser, &available_message) { Ok((_, out)) => out, Err(_) => { return Err(HandshakeError::PayloadDecode(PayloadDecodeError)); @@ -905,21 +902,19 @@ impl HandshakeInProgress { ) = { // Because the remote hasn't fully authenticated us at this point, sending // more data than what the protocol specifies is forbidden. - let mut parser = nom::combinator::all_consuming::< - _, - _, - (&[u8], nom::error::ErrorKind), - _, - >(nom::sequence::tuple(( - nom::combinator::map(nom::bytes::streaming::take(32u32), |k| { - <&[u8; 32]>::try_from(k).unwrap() - }), - nom::combinator::map(nom::bytes::streaming::take(48u32), |k| { - <&[u8; 48]>::try_from(k).unwrap() - }), - nom::combinator::rest, - ))); - match parser(&available_message) { + let mut parser = + nom::combinator::all_consuming::<_, (&[u8], nom::error::ErrorKind), _>( + ( + nom::combinator::map(nom::bytes::streaming::take(32u32), |k| { + <&[u8; 32]>::try_from(k).unwrap() + }), + nom::combinator::map(nom::bytes::streaming::take(48u32), |k| { + <&[u8; 48]>::try_from(k).unwrap() + }), + nom::combinator::rest, + ), + ); + match nom::Parser::parse(&mut parser, &available_message) { Ok((_, out)) => out, Err(_) => { return Err(HandshakeError::PayloadDecode(PayloadDecodeError)); @@ -990,7 +985,6 @@ impl HandshakeInProgress { let (libp2p_key, libp2p_signature) = { let mut parser = nom::combinator::all_consuming::< - _, _, (&[u8], nom::error::ErrorKind), _, @@ -998,7 +992,7 @@ impl HandshakeInProgress { #[required] key = 1 => protobuf::bytes_tag_decode, #[required] sig = 2 => protobuf::bytes_tag_decode, }); - match parser(&libp2p_handshake_decrypted) { + match nom::Parser::parse(&mut parser, &libp2p_handshake_decrypted) { Ok((_, out)) => (out.key, out.sig), Err(_) => { return Err(HandshakeError::PayloadDecode(PayloadDecodeError)); @@ -1032,18 +1026,16 @@ impl HandshakeInProgress { // handshake message and a noise transport message as two different things. // While the remote could in theory send post-handshake // application-specific data in this message, in practice it is forbidden. - let mut parser = nom::combinator::all_consuming::< - _, - _, - (&[u8], nom::error::ErrorKind), - _, - >(nom::sequence::tuple(( - nom::combinator::map(nom::bytes::streaming::take(48u32), |k| { - <&[u8; 48]>::try_from(k).unwrap() - }), - nom::combinator::rest, - ))); - match parser(&available_message) { + let mut parser = + nom::combinator::all_consuming::<_, (&[u8], nom::error::ErrorKind), _>( + ( + nom::combinator::map(nom::bytes::streaming::take(48u32), |k| { + <&[u8; 48]>::try_from(k).unwrap() + }), + nom::combinator::rest, + ), + ); + match nom::Parser::parse(&mut parser, &available_message) { Ok((_, out)) => out, Err(_) => { return Err(HandshakeError::PayloadDecode(PayloadDecodeError)); @@ -1092,7 +1084,6 @@ impl HandshakeInProgress { let (libp2p_key, libp2p_signature) = { let mut parser = nom::combinator::all_consuming::< - _, _, (&[u8], nom::error::ErrorKind), _, @@ -1100,7 +1091,7 @@ impl HandshakeInProgress { #[required] key = 1 => protobuf::bytes_tag_decode, #[required] sig = 2 => protobuf::bytes_tag_decode, }); - match parser(&libp2p_handshake_decrypted) { + match nom::Parser::parse(&mut parser, &libp2p_handshake_decrypted) { Ok((_, out)) => (out.key, out.sig), Err(_) => { return Err(HandshakeError::PayloadDecode(PayloadDecodeError)); diff --git a/lib/src/libp2p/connection/webrtc_framing.rs b/lib/src/libp2p/connection/webrtc_framing.rs index 36c7be963b..156f21f21c 100644 --- a/lib/src/libp2p/connection/webrtc_framing.rs +++ b/lib/src/libp2p/connection/webrtc_framing.rs @@ -104,15 +104,14 @@ impl WebRtcFraming { // Try to parse a frame from the incoming buffer. let bytes_to_discard = { // TODO: we could in theory demand from the outside just the protobuf header, and then later the data, which would save some copying but might considerably complexifies the code - let mut parser = - nom::combinator::map_parser::<_, _, _, nom::error::Error<&[u8]>, _, _>( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - protobuf::message_decode! { - #[optional] flags = 1 => protobuf::enum_tag_decode, - #[optional] message = 2 => protobuf::bytes_tag_decode, - }, - ); - match parser(&outer_read_write.incoming_buffer) { + let mut parser = nom::combinator::map_parser::<_, _, nom::error::Error<&[u8]>, _, _>( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + protobuf::message_decode! { + #[optional] flags = 1 => protobuf::enum_tag_decode, + #[optional] message = 2 => protobuf::bytes_tag_decode, + }, + ); + match nom::Parser::parse(&mut parser, &outer_read_write.incoming_buffer) { Ok((rest, framed_message)) => { // The remote has sent a `RESET_STREAM` flag, immediately stop with an error. // The specification mentions that the receiver may discard any data already diff --git a/lib/src/libp2p/connection/yamux/header.rs b/lib/src/libp2p/connection/yamux/header.rs index 03aa9ae7c3..7fd8f3df93 100644 --- a/lib/src/libp2p/connection/yamux/header.rs +++ b/lib/src/libp2p/connection/yamux/header.rs @@ -162,7 +162,10 @@ pub fn encode(header: &DecodedYamuxHeader) -> [u8; 12] { /// Decodes a Yamux header. pub fn decode_yamux_header(bytes: &[u8; 12]) -> Result { - match nom::combinator::all_consuming(nom::combinator::complete(decode))(bytes) { + match nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(decode)), + bytes, + ) { Ok((_, h)) => Ok(h), Err(nom::Err::Incomplete(_)) => unreachable!(), Err(nom::Err::Failure(err) | nom::Err::Error(err)) => Err(YamuxHeaderDecodeError { @@ -179,96 +182,108 @@ pub struct YamuxHeaderDecodeError { } fn decode(bytes: &[u8]) -> nom::IResult<&[u8], DecodedYamuxHeader> { - nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), - nom::branch::alt(( - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::tag(&[0]), - flags, - nom::combinator::map_opt(nom::number::streaming::be_u32, NonZero::::new), - nom::number::streaming::be_u32, - )), - |(_, (syn, ack, fin, rst), stream_id, length)| DecodedYamuxHeader::Data { - syn, - ack, - fin, - rst, - stream_id, - length, - }, - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::tag(&[1]), - flags, - nom::combinator::map_opt(nom::number::streaming::be_u32, NonZero::::new), - nom::number::streaming::be_u32, - )), - |(_, (syn, ack, fin, rst), stream_id, length)| DecodedYamuxHeader::Window { - syn, - ack, - fin, - rst, - stream_id, - length, - }, - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::tag(&[2]), - nom::bytes::streaming::tag(&[0x0, 0x1]), - nom::bytes::streaming::tag(&[0, 0, 0, 0]), - nom::number::streaming::be_u32, - )), - |(_, _, _, opaque_value)| DecodedYamuxHeader::PingRequest { opaque_value }, - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::tag(&[2]), - nom::bytes::streaming::tag(&[0x0, 0x2]), - nom::bytes::streaming::tag(&[0, 0, 0, 0]), - nom::number::streaming::be_u32, - )), - |(_, _, _, opaque_value)| DecodedYamuxHeader::PingResponse { opaque_value }, - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::tag(&[3]), - nom::bytes::streaming::tag(&[0, 0]), - nom::bytes::streaming::tag(&[0, 0, 0, 0]), - nom::branch::alt(( - nom::combinator::map( - nom::bytes::streaming::tag(0u32.to_be_bytes()), - |_| GoAwayErrorCode::NormalTermination, + nom::Parser::parse( + &mut nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + nom::branch::alt(( + nom::combinator::map( + ( + nom::bytes::streaming::tag(&[0][..]), + flags, + nom::combinator::map_opt( + nom::number::streaming::be_u32, + NonZero::::new, ), - nom::combinator::map( - nom::bytes::streaming::tag(1u32.to_be_bytes()), - |_| GoAwayErrorCode::ProtocolError, + nom::number::streaming::be_u32, + ), + |(_, (syn, ack, fin, rst), stream_id, length)| DecodedYamuxHeader::Data { + syn, + ack, + fin, + rst, + stream_id, + length, + }, + ), + nom::combinator::map( + ( + nom::bytes::streaming::tag(&[1][..]), + flags, + nom::combinator::map_opt( + nom::number::streaming::be_u32, + NonZero::::new, ), - nom::combinator::map( - nom::bytes::streaming::tag(2u32.to_be_bytes()), - |_| GoAwayErrorCode::InternalError, - ), - )), - )), - |(_, _, _, error_code)| DecodedYamuxHeader::GoAway { error_code }, - ), - )), - )(bytes) + nom::number::streaming::be_u32, + ), + |(_, (syn, ack, fin, rst), stream_id, length)| DecodedYamuxHeader::Window { + syn, + ack, + fin, + rst, + stream_id, + length, + }, + ), + nom::combinator::map( + ( + nom::bytes::streaming::tag(&[2][..]), + nom::bytes::streaming::tag(&[0x0, 0x1][..]), + nom::bytes::streaming::tag(&[0, 0, 0, 0][..]), + nom::number::streaming::be_u32, + ), + |(_, _, _, opaque_value)| DecodedYamuxHeader::PingRequest { opaque_value }, + ), + nom::combinator::map( + ( + nom::bytes::streaming::tag(&[2][..]), + nom::bytes::streaming::tag(&[0x0, 0x2][..]), + nom::bytes::streaming::tag(&[0, 0, 0, 0][..]), + nom::number::streaming::be_u32, + ), + |(_, _, _, opaque_value)| DecodedYamuxHeader::PingResponse { opaque_value }, + ), + nom::combinator::map( + ( + nom::bytes::streaming::tag(&[3][..]), + nom::bytes::streaming::tag(&[0, 0][..]), + nom::bytes::streaming::tag(&[0, 0, 0, 0][..]), + nom::branch::alt(( + nom::combinator::map( + nom::bytes::streaming::tag(&0u32.to_be_bytes()[..]), + |_| GoAwayErrorCode::NormalTermination, + ), + nom::combinator::map( + nom::bytes::streaming::tag(&1u32.to_be_bytes()[..]), + |_| GoAwayErrorCode::ProtocolError, + ), + nom::combinator::map( + nom::bytes::streaming::tag(&2u32.to_be_bytes()[..]), + |_| GoAwayErrorCode::InternalError, + ), + )), + ), + |(_, _, _, error_code)| DecodedYamuxHeader::GoAway { error_code }, + ), + )), + ), + bytes, + ) } fn flags(bytes: &[u8]) -> nom::IResult<&[u8], (bool, bool, bool, bool)> { - nom::combinator::map_opt(nom::number::streaming::be_u16, |flags| { - let syn = (flags & 0x1) != 0; - let ack = (flags & 0x2) != 0; - let fin = (flags & 0x4) != 0; - let rst = (flags & 0x8) != 0; - if (flags & !0b1111) != 0 { - return None; - } - Some((syn, ack, fin, rst)) - })(bytes) + nom::Parser::parse( + &mut nom::combinator::map_opt(nom::number::streaming::be_u16, |flags| { + let syn = (flags & 0x1) != 0; + let ack = (flags & 0x2) != 0; + let fin = (flags & 0x4) != 0; + let rst = (flags & 0x8) != 0; + if (flags & !0b1111) != 0 { + return None; + } + Some((syn, ack, fin, rst)) + }), + bytes, + ) } #[cfg(test)] diff --git a/lib/src/libp2p/multiaddr.rs b/lib/src/libp2p/multiaddr.rs index 2b889495e9..3d4b68fd61 100644 --- a/lib/src/libp2p/multiaddr.rs +++ b/lib/src/libp2p/multiaddr.rs @@ -57,7 +57,7 @@ impl Multiaddr> { /// pub fn pop(&mut self) { let remain = { - let mut iter = nom::combinator::iterator( + let iter = nom::combinator::iterator( &self.bytes[..], nom::combinator::recognize(protocol::<&[u8], nom::error::Error<&[u8]>>), ); @@ -82,11 +82,14 @@ impl> Multiaddr { /// around a [`Multiaddr`]. pub fn from_bytes(bytes: T) -> Result { // Check whether this is indeed a valid list of protocols. - if nom::combinator::all_consuming(nom::multi::fold_many0( - nom::combinator::complete(protocol::<&[u8], nom::error::Error<&[u8]>>), - || (), - |(), _| (), - ))(bytes.as_ref()) + if nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::multi::fold_many0( + nom::combinator::complete(protocol::<&[u8], nom::error::Error<&[u8]>>), + || (), + |(), _| (), + )), + bytes.as_ref(), + ) .is_err() { return Err((FromBytesError, bytes)); @@ -494,71 +497,109 @@ impl> fmt::Display for DomainName { fn protocol<'a, T: From<&'a [u8]> + AsRef<[u8]>, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], Protocol, E> { - nom::combinator::flat_map(crate::util::leb128::nom_leb128_usize, |protocol_code| { - move |bytes: &'a [u8]| match protocol_code { - 4 => nom::combinator::map(nom::bytes::streaming::take(4_u32), |ip: &'a [u8]| { - Protocol::Ip4(ip.try_into().unwrap()) - })(bytes), - 6 => nom::combinator::map(nom::number::streaming::be_u16, Protocol::Tcp)(bytes), - 41 => nom::combinator::map(nom::bytes::streaming::take(16_u32), |ip: &'a [u8]| { - Protocol::Ip6(ip.try_into().unwrap()) - })(bytes), - 53 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| DomainName::from_bytes(T::from(s)).ok(), + nom::Parser::parse( + &mut nom::combinator::flat_map(crate::util::leb128::nom_leb128_usize, |protocol_code| { + move |bytes: &'a [u8]| match protocol_code { + 4 => nom::Parser::parse( + &mut nom::combinator::map( + nom::bytes::streaming::take(4_u32), + |ip: &'a [u8]| Protocol::Ip4(ip.try_into().unwrap()), + ), + bytes, ), - Protocol::Dns, - )(bytes), - 54 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| DomainName::from_bytes(T::from(s)).ok(), + 6 => nom::Parser::parse( + &mut nom::combinator::map(nom::number::streaming::be_u16, Protocol::Tcp), + bytes, ), - Protocol::Dns4, - )(bytes), - 55 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| DomainName::from_bytes(T::from(s)).ok(), + 41 => nom::Parser::parse( + &mut nom::combinator::map( + nom::bytes::streaming::take(16_u32), + |ip: &'a [u8]| Protocol::Ip6(ip.try_into().unwrap()), + ), + bytes, ), - Protocol::Dns6, - )(bytes), - 56 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| DomainName::from_bytes(T::from(s)).ok(), + 53 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| DomainName::from_bytes(T::from(s)).ok(), + ), + Protocol::Dns, + ), + bytes, ), - Protocol::DnsAddr, - )(bytes), - 273 => nom::combinator::map(nom::number::streaming::be_u16, Protocol::Udp)(bytes), - 421 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| Multihash::from_bytes(From::from(s)).ok(), + 54 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| DomainName::from_bytes(T::from(s)).ok(), + ), + Protocol::Dns4, + ), + bytes, ), - Protocol::P2p, - )(bytes), - 448 => Ok((bytes, Protocol::Tls)), - 460 => Ok((bytes, Protocol::Quic)), - 477 => Ok((bytes, Protocol::Ws)), - 478 => Ok((bytes, Protocol::Wss)), - // TODO: unclear what the /memory payload is, see https://github.com/multiformats/multiaddr/issues/127 - 777 => nom::combinator::map(nom::number::streaming::be_u64, Protocol::Memory)(bytes), - 280 => Ok((bytes, Protocol::WebRtcDirect)), - 466 => nom::combinator::map( - nom::combinator::map_opt( - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - |s| Multihash::from_bytes(From::from(s)).ok(), + 55 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| DomainName::from_bytes(T::from(s)).ok(), + ), + Protocol::Dns6, + ), + bytes, ), - Protocol::Certhash, - )(bytes), - _ => Err(nom::Err::Error(nom::error::make_error( - bytes, - nom::error::ErrorKind::Tag, - ))), - } - })(bytes) + 56 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| DomainName::from_bytes(T::from(s)).ok(), + ), + Protocol::DnsAddr, + ), + bytes, + ), + 273 => nom::Parser::parse( + &mut nom::combinator::map(nom::number::streaming::be_u16, Protocol::Udp), + bytes, + ), + 421 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| Multihash::from_bytes(From::from(s)).ok(), + ), + Protocol::P2p, + ), + bytes, + ), + 448 => Ok((bytes, Protocol::Tls)), + 460 => Ok((bytes, Protocol::Quic)), + 477 => Ok((bytes, Protocol::Ws)), + 478 => Ok((bytes, Protocol::Wss)), + // TODO: unclear what the /memory payload is, see https://github.com/multiformats/multiaddr/issues/127 + 777 => nom::Parser::parse( + &mut nom::combinator::map(nom::number::streaming::be_u64, Protocol::Memory), + bytes, + ), + 280 => Ok((bytes, Protocol::WebRtcDirect)), + 466 => nom::Parser::parse( + &mut nom::combinator::map( + nom::combinator::map_opt( + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + |s| Multihash::from_bytes(From::from(s)).ok(), + ), + Protocol::Certhash, + ), + bytes, + ), + _ => Err(nom::Err::Error(nom::error::make_error( + bytes, + nom::error::ErrorKind::Tag, + ))), + } + }), + bytes, + ) } #[cfg(test)] diff --git a/lib/src/libp2p/multihash.rs b/lib/src/libp2p/multihash.rs index 69f3ee0cb5..1810312dc3 100644 --- a/lib/src/libp2p/multihash.rs +++ b/lib/src/libp2p/multihash.rs @@ -119,7 +119,10 @@ impl> fmt::Display for Multihash { } fn decode(bytes: &[u8]) -> Result<(u32, &[u8]), FromBytesError> { - match nom::combinator::all_consuming(multihash::>)(bytes) { + match nom::Parser::parse( + &mut nom::combinator::all_consuming(multihash::>), + bytes, + ) { Ok((_rest, multihash)) => { debug_assert!(_rest.is_empty()); Ok(multihash) @@ -131,10 +134,13 @@ fn decode(bytes: &[u8]) -> Result<(u32, &[u8]), FromBytesError> { fn multihash<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], (u32, &'a [u8]), E> { - nom::sequence::tuple(( - nom::combinator::map_opt(crate::util::leb128::nom_leb128_usize, |c| { - u32::try_from(c).ok() - }), - nom::multi::length_data(crate::util::leb128::nom_leb128_usize), - ))(bytes) + nom::Parser::parse( + &mut ( + nom::combinator::map_opt(crate::util::leb128::nom_leb128_usize, |c| { + u32::try_from(c).ok() + }), + nom::multi::length_data(crate::util::leb128::nom_leb128_usize), + ), + bytes, + ) } diff --git a/lib/src/libp2p/peer_id.rs b/lib/src/libp2p/peer_id.rs index 3f7c8af85c..7fc415fb11 100644 --- a/lib/src/libp2p/peer_id.rs +++ b/lib/src/libp2p/peer_id.rs @@ -79,8 +79,8 @@ impl PublicKey { // As indicated in the libp2p specification, the public key must be encoded // deterministically, and thus the fields are decoded deterministically in a precise order. - let mut parser = nom::combinator::all_consuming::<_, _, ErrorWrapper, _>( - nom::combinator::complete(nom::sequence::tuple(( + let mut parser = + nom::combinator::all_consuming::<_, ErrorWrapper, _>(nom::combinator::complete(( nom::sequence::preceded( nom::combinator::peek(nom::combinator::verify( protobuf::tag_decode, @@ -101,10 +101,9 @@ impl PublicKey { .map_err(|_| FromProtobufEncodingError::BadEd25519Key) }), ), - ))), - ); + ))); - match nom::Finish::finish(parser(bytes)) { + match nom::Finish::finish(nom::Parser::parse(&mut parser, bytes)) { Ok((_, (1, key))) => Ok(PublicKey::Ed25519(key)), Ok((_, (_, _))) => Err(FromProtobufEncodingError::UnsupportedAlgorithm), Err(err) => Err(err.0), diff --git a/lib/src/network/codec.rs b/lib/src/network/codec.rs index d8d6cf6dcd..51fe27a4b6 100644 --- a/lib/src/network/codec.rs +++ b/lib/src/network/codec.rs @@ -176,48 +176,54 @@ pub fn encode_protocol_name_string(protocol: ProtocolName) -> String { /// /// Returns an error if the protocol name isn't recognized. pub fn decode_protocol_name(name: &str) -> Result { - nom::combinator::all_consuming(nom::branch::alt(( - nom::combinator::map(nom::bytes::complete::tag("/ipfs/id/1.0.0"), |_| { - ProtocolName::Identify - }), - nom::combinator::map(nom::bytes::complete::tag("/ipfs/ping/1.0.0"), |_| { - ProtocolName::Ping - }), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::complete::tag("/"), - genesis_hash, - nom::bytes::complete::tag("/"), - protocol_ty, - )), - |(_, genesis_hash, _, protocol_ty)| { - protocol_ty_to_real_protocol(protocol_ty, genesis_hash, None) - }, - ), - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::complete::tag("/"), - genesis_hash, - nom::bytes::complete::tag("/"), - nom::bytes::complete::take_until("/"), - nom::bytes::complete::tag("/"), - protocol_ty, - )), - |(_, genesis_hash, _, fork_id, _, protocol_ty)| { - protocol_ty_to_real_protocol(protocol_ty, genesis_hash, Some(fork_id)) - }, - ), - )))(name) + nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::branch::alt(( + nom::combinator::map(nom::bytes::complete::tag("/ipfs/id/1.0.0"), |_| { + ProtocolName::Identify + }), + nom::combinator::map(nom::bytes::complete::tag("/ipfs/ping/1.0.0"), |_| { + ProtocolName::Ping + }), + nom::combinator::map( + ( + nom::bytes::complete::tag("/"), + genesis_hash, + nom::bytes::complete::tag("/"), + protocol_ty, + ), + |(_, genesis_hash, _, protocol_ty)| { + protocol_ty_to_real_protocol(protocol_ty, genesis_hash, None) + }, + ), + nom::combinator::map( + ( + nom::bytes::complete::tag("/"), + genesis_hash, + nom::bytes::complete::tag("/"), + nom::bytes::complete::take_until("/"), + nom::bytes::complete::tag("/"), + protocol_ty, + ), + |(_, genesis_hash, _, fork_id, _, protocol_ty)| { + protocol_ty_to_real_protocol(protocol_ty, genesis_hash, Some(fork_id)) + }, + ), + ))), + name, + ) .map(|(_, parse_result)| parse_result) .map_err(|_| ()) } fn genesis_hash(name: &str) -> nom::IResult<&str, [u8; 32]> { - nom::combinator::map_opt(nom::bytes::complete::take(64u32), |hash| { - hex::decode(hash) - .ok() - .map(|hash| <[u8; 32]>::try_from(hash).unwrap_or_else(|_| unreachable!())) - })(name) + nom::Parser::parse( + &mut nom::combinator::map_opt(nom::bytes::complete::take(64u32), |hash| { + hex::decode(hash) + .ok() + .map(|hash| <[u8; 32]>::try_from(hash).unwrap_or_else(|_| unreachable!())) + }), + name, + ) } enum ProtocolTy { @@ -232,24 +238,27 @@ enum ProtocolTy { } fn protocol_ty(name: &str) -> nom::IResult<&str, ProtocolTy> { - nom::branch::alt(( - nom::combinator::map(nom::bytes::complete::tag("block-announces/1"), |_| { - ProtocolTy::BlockAnnounces - }), - nom::combinator::map(nom::bytes::complete::tag("transactions/1"), |_| { - ProtocolTy::Transactions - }), - nom::combinator::map(nom::bytes::complete::tag("grandpa/1"), |_| { - ProtocolTy::Grandpa - }), - nom::combinator::map(nom::bytes::complete::tag("sync/2"), |_| ProtocolTy::Sync), - nom::combinator::map(nom::bytes::complete::tag("light/2"), |_| ProtocolTy::Light), - nom::combinator::map(nom::bytes::complete::tag("kad"), |_| ProtocolTy::Kad), - nom::combinator::map(nom::bytes::complete::tag("sync/warp"), |_| { - ProtocolTy::SyncWarp - }), - nom::combinator::map(nom::bytes::complete::tag("state/2"), |_| ProtocolTy::State), - ))(name) + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map(nom::bytes::complete::tag("block-announces/1"), |_| { + ProtocolTy::BlockAnnounces + }), + nom::combinator::map(nom::bytes::complete::tag("transactions/1"), |_| { + ProtocolTy::Transactions + }), + nom::combinator::map(nom::bytes::complete::tag("grandpa/1"), |_| { + ProtocolTy::Grandpa + }), + nom::combinator::map(nom::bytes::complete::tag("sync/2"), |_| ProtocolTy::Sync), + nom::combinator::map(nom::bytes::complete::tag("light/2"), |_| ProtocolTy::Light), + nom::combinator::map(nom::bytes::complete::tag("kad"), |_| ProtocolTy::Kad), + nom::combinator::map(nom::bytes::complete::tag("sync/warp"), |_| { + ProtocolTy::SyncWarp + }), + nom::combinator::map(nom::bytes::complete::tag("state/2"), |_| ProtocolTy::State), + )), + name, + ) } fn protocol_ty_to_real_protocol( diff --git a/lib/src/network/codec/block_announces.rs b/lib/src/network/codec/block_announces.rs index 7f8f2b75b3..45291e2ca7 100644 --- a/lib/src/network/codec/block_announces.rs +++ b/lib/src/network/codec/block_announces.rs @@ -106,9 +106,9 @@ pub fn decode_block_announce( bytes: &[u8], block_number_bytes: usize, ) -> Result { - let result: Result<_, nom::error::Error<_>> = - nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( - nom::sequence::tuple(( + let result: Result<_, nom::error::Error<_>> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( + ( nom::combinator::recognize(|enc_hdr| { match header::decode_partial(enc_hdr, block_number_bytes) { Ok((hdr, rest)) => Ok((rest, hdr)), @@ -119,17 +119,19 @@ pub fn decode_block_announce( } }), nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| false), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| true), + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| false), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| true), )), crate::util::nom_bytes_decode, - )), + ), |(scale_encoded_header, is_best, _)| BlockAnnounceRef { scale_encoded_header, is_best, }, - )))(bytes) - .finish(); + ))), + bytes, + ) + .finish(); match result { Ok((_, ann)) => Ok(ann), @@ -169,26 +171,30 @@ pub fn decode_block_announces_handshake( expected_block_number_bytes: usize, handshake: &[u8], ) -> Result { - let result: Result<_, nom::error::Error<_>> = - nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( - nom::sequence::tuple(( + let result: Result<_, nom::error::Error<_>> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( + ( nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0b1]), |_| Role::Full), - nom::combinator::map(nom::bytes::streaming::tag(&[0b10]), |_| Role::Light), - nom::combinator::map(nom::bytes::streaming::tag(&[0b100]), |_| Role::Authority), + nom::combinator::map(nom::bytes::streaming::tag(&[0b1][..]), |_| Role::Full), + nom::combinator::map(nom::bytes::streaming::tag(&[0b10][..]), |_| Role::Light), + nom::combinator::map(nom::bytes::streaming::tag(&[0b100][..]), |_| { + Role::Authority + }), )), crate::util::nom_varsize_number_decode_u64(expected_block_number_bytes), nom::bytes::streaming::take(32u32), nom::bytes::streaming::take(32u32), - )), + ), |(role, best_number, best_hash, genesis_hash)| BlockAnnouncesHandshakeRef { role, best_number, best_hash: TryFrom::try_from(best_hash).unwrap(), genesis_hash: TryFrom::try_from(genesis_hash).unwrap(), }, - )))(handshake) - .finish(); + ))), + handshake, + ) + .finish(); match result { Ok((_, hs)) => Ok(hs), diff --git a/lib/src/network/codec/block_request.rs b/lib/src/network/codec/block_request.rs index 655c16820a..a432433ecf 100644 --- a/lib/src/network/codec/block_request.rs +++ b/lib/src/network/codec/block_request.rs @@ -137,7 +137,7 @@ pub fn decode_block_request( expected_block_number_bytes: usize, request_bytes: &[u8], ) -> Result { - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[required] fields = 1 => protobuf::uint32_tag_decode, #[optional] hash = 2 => protobuf::bytes_tag_decode, @@ -147,7 +147,7 @@ pub fn decode_block_request( }), ); - let decoded = match nom::Finish::finish(parser(request_bytes)) { + let decoded = match nom::Finish::finish(nom::Parser::parse(&mut parser, request_bytes)) { Ok((_, rq)) => rq, Err(_) => return Err(DecodeBlockRequestError::ProtobufDecode), }; @@ -275,7 +275,7 @@ pub fn build_block_response(response: Vec) -> impl Iterator Result, DecodeBlockResponseError> { - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[repeated(max = 32768)] blocks = 1 => protobuf::message_tag_decode(protobuf::message_decode!{ #[required] hash = 1 => protobuf::bytes_tag_decode, @@ -286,7 +286,7 @@ pub fn decode_block_response( }), ); - let blocks = match nom::Finish::finish(parser(response_bytes)) { + let blocks = match nom::Finish::finish(nom::Parser::parse(&mut parser, response_bytes)) { Ok((_, out)) => out.blocks, Err(_) => return Err(DecodeBlockResponseError::ProtobufDecode), }; @@ -303,9 +303,12 @@ pub fn decode_block_response( // TODO: no; we might not have asked for the body body: Some(block.body.into_iter().map(|tx| tx.to_vec()).collect()), justifications: if let Some(justifications) = block.justifications { - let result: nom::IResult<_, _> = nom::combinator::all_consuming( - nom::combinator::complete(decode_justifications), - )(justifications); + let result: nom::IResult<_, _> = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::complete( + decode_justifications, + )), + justifications, + ); match result { Ok((_, out)) => Some(out), Err(nom::Err::Error(_) | nom::Err::Failure(_)) => { @@ -398,22 +401,25 @@ pub enum DecodeBlockResponseError { fn decode_justifications<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], Vec, E> { - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::combinator::map( - nom::sequence::tuple(( - nom::bytes::streaming::take(4u32), - crate::util::nom_bytes_decode, - )), - move |(consensus_engine, justification)| Justification { - engine_id: <[u8; 4]>::try_from(consensus_engine).unwrap(), - justification: justification.to_owned(), - }, - ), - ) - })(bytes) + nom::Parser::parse( + &mut nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + nom::combinator::map( + ( + nom::bytes::streaming::take(4u32), + crate::util::nom_bytes_decode, + ), + move |(consensus_engine, justification)| Justification { + engine_id: <[u8; 4]>::try_from(consensus_engine).unwrap(), + justification: justification.to_owned(), + }, + ), + ) + }), + bytes, + ) } #[cfg(test)] diff --git a/lib/src/network/codec/grandpa.rs b/lib/src/network/codec/grandpa.rs index f1702818a3..720814141e 100644 --- a/lib/src/network/codec/grandpa.rs +++ b/lib/src/network/codec/grandpa.rs @@ -151,9 +151,12 @@ pub fn decode_grandpa_notification( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result { - match nom::combinator::all_consuming(nom::combinator::complete(grandpa_notification( - block_number_bytes, - )))(scale_encoded) + match nom::Parser::parse( + &mut nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( + nom::combinator::complete(grandpa_notification(block_number_bytes)), + ), + scale_encoded, + ) .finish() { Ok((_, notif)) => Ok(notif), @@ -169,21 +172,24 @@ pub struct DecodeGrandpaNotificationError(#[error(not(source))] nom::error::Erro // Nom combinators below. -fn grandpa_notification<'a>( +fn grandpa_notification< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], GrandpaNotificationRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = GrandpaNotificationRef<'a>, Error = E> { nom::error::context( "grandpa_notification", nom::branch::alt(( nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), + nom::bytes::streaming::tag(&[0][..]), vote_message(block_number_bytes), ), GrandpaNotificationRef::Vote, ), nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), move |s| { + nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), move |s| { decode::decode_partial_grandpa_commit(s, block_number_bytes) .map(|(a, b)| (b, a)) .map_err(|_| { @@ -197,18 +203,18 @@ fn grandpa_notification<'a>( ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), + nom::bytes::streaming::tag(&[2][..]), neighbor_packet(block_number_bytes), ), GrandpaNotificationRef::Neighbor, ), nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[3]), catch_up_request), + nom::sequence::preceded(nom::bytes::streaming::tag(&[3][..]), catch_up_request), GrandpaNotificationRef::CatchUpRequest, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[4]), + nom::bytes::streaming::tag(&[4][..]), catch_up(block_number_bytes), ), GrandpaNotificationRef::CatchUp, @@ -217,19 +223,19 @@ fn grandpa_notification<'a>( ) } -fn vote_message<'a>( +fn vote_message<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], VoteMessageRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = VoteMessageRef<'a>, Error = E> { nom::error::context( "vote_message", nom::combinator::map( - nom::sequence::tuple(( + ( nom::number::streaming::le_u64, nom::number::streaming::le_u64, message(block_number_bytes), nom::bytes::streaming::take(64u32), nom::bytes::streaming::take(32u32), - )), + ), |(round_number, set_id, message, signature, authority_public_key)| VoteMessageRef { round_number, set_id, @@ -241,29 +247,29 @@ fn vote_message<'a>( ) } -fn message<'a>( +fn message<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], MessageRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = MessageRef<'a>, Error = E> { nom::error::context( "message", nom::branch::alt(( nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[0]), + nom::bytes::streaming::tag(&[0][..]), unsigned_prevote(block_number_bytes), ), MessageRef::Prevote, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), + nom::bytes::streaming::tag(&[1][..]), unsigned_precommit(block_number_bytes), ), MessageRef::Precommit, ), nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), + nom::bytes::streaming::tag(&[2][..]), primary_propose(block_number_bytes), ), MessageRef::PrimaryPropose, @@ -272,16 +278,19 @@ fn message<'a>( ) } -fn unsigned_prevote<'a>( +fn unsigned_prevote< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], UnsignedPrevoteRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = UnsignedPrevoteRef<'a>, Error = E> { nom::error::context( "unsigned_prevote", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(target_hash, target_number)| UnsignedPrevoteRef { target_hash: <&[u8; 32]>::try_from(target_hash).unwrap(), target_number, @@ -290,16 +299,19 @@ fn unsigned_prevote<'a>( ) } -fn unsigned_precommit<'a>( +fn unsigned_precommit< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], UnsignedPrecommitRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = UnsignedPrecommitRef<'a>, Error = E> { nom::error::context( "unsigned_precommit", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(target_hash, target_number)| UnsignedPrecommitRef { target_hash: <&[u8; 32]>::try_from(target_hash).unwrap(), target_number, @@ -308,16 +320,16 @@ fn unsigned_precommit<'a>( ) } -fn primary_propose<'a>( +fn primary_propose<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], PrimaryProposeRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = PrimaryProposeRef<'a>, Error = E> { nom::error::context( "primary_propose", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(target_hash, target_number)| PrimaryProposeRef { target_hash: <&[u8; 32]>::try_from(target_hash).unwrap(), target_number, @@ -326,19 +338,19 @@ fn primary_propose<'a>( ) } -fn neighbor_packet<'a>( +fn neighbor_packet<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], NeighborPacket> { +) -> impl nom::Parser<&'a [u8], Output = NeighborPacket, Error = E> { nom::error::context( "neighbor_packet", nom::combinator::map( nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), - nom::sequence::tuple(( + nom::bytes::streaming::tag(&[1][..]), + ( nom::number::streaming::le_u64, nom::number::streaming::le_u64, crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), ), |(round_number, set_id, commit_finalized_height)| NeighborPacket { round_number, @@ -349,29 +361,37 @@ fn neighbor_packet<'a>( ) } -fn catch_up_request(bytes: &[u8]) -> nom::IResult<&[u8], CatchUpRequest> { - nom::error::context( - "catch_up_request", - nom::combinator::map( - nom::sequence::tuple(( - nom::number::streaming::le_u64, - nom::number::streaming::le_u64, - )), - |(round_number, set_id)| CatchUpRequest { - round_number, - set_id, - }, +fn catch_up_request< + 'a, + E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>, +>( + bytes: &'a [u8], +) -> nom::IResult<&'a [u8], CatchUpRequest, E> { + nom::Parser::parse( + &mut nom::error::context( + "catch_up_request", + nom::combinator::map( + ( + nom::number::streaming::le_u64, + nom::number::streaming::le_u64, + ), + |(round_number, set_id)| CatchUpRequest { + round_number, + set_id, + }, + ), ), - )(bytes) + bytes, + ) } -fn catch_up<'a>( +fn catch_up<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], CatchUpRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = CatchUpRef<'a>, Error = E> { nom::error::context( "catch_up", nom::combinator::map( - nom::sequence::tuple(( + ( nom::number::streaming::le_u64, nom::number::streaming::le_u64, nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { @@ -391,7 +411,7 @@ fn catch_up<'a>( }), nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), - )), + ), |(set_id, round_number, prevotes, precommits, base_hash, base_number)| CatchUpRef { set_id, round_number, @@ -404,18 +424,18 @@ fn catch_up<'a>( ) } -fn prevote<'a>( +fn prevote<'a, E: nom::error::ContextError<&'a [u8]> + nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], PrevoteRef<'a>> { +) -> impl nom::Parser<&'a [u8], Output = PrevoteRef<'a>, Error = E> { nom::error::context( "prevote", nom::combinator::map( - nom::sequence::tuple(( + ( nom::bytes::streaming::take(32u32), crate::util::nom_varsize_number_decode_u64(block_number_bytes), nom::bytes::streaming::take(64u32), nom::bytes::streaming::take(32u32), - )), + ), |(target_hash, target_number, signature, authority_public_key)| PrevoteRef { target_hash: <&[u8; 32]>::try_from(target_hash).unwrap(), target_number, diff --git a/lib/src/network/codec/grandpa_warp_sync.rs b/lib/src/network/codec/grandpa_warp_sync.rs index 57a402144e..89d8dacb6a 100644 --- a/lib/src/network/codec/grandpa_warp_sync.rs +++ b/lib/src/network/codec/grandpa_warp_sync.rs @@ -79,33 +79,38 @@ pub fn decode_grandpa_warp_sync_response( encoded: &[u8], block_number_bytes: usize, ) -> Result { - nom::combinator::all_consuming(nom::combinator::map( - nom::sequence::tuple(( - decode_fragments(block_number_bytes), - nom::number::streaming::le_u8, - )), - |(fragments, is_finished)| GrandpaWarpSyncResponse { - fragments, - is_finished: is_finished != 0, - }, - ))(encoded) + nom::Parser::parse( + &mut nom::combinator::all_consuming::<_, (&[u8], nom::error::ErrorKind), _>( + nom::combinator::map( + ( + decode_fragments(block_number_bytes), + nom::number::streaming::le_u8, + ), + |(fragments, is_finished)| GrandpaWarpSyncResponse { + fragments, + is_finished: is_finished != 0, + }, + ), + ), + encoded, + ) .map(|(_, parse_result)| parse_result) .map_err(|_| DecodeGrandpaWarpSyncResponseError) } -fn decode_fragments<'a>( +fn decode_fragments<'a, E: nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], Vec>> { +) -> impl nom::Parser<&'a [u8], Output = Vec>, Error = E> { nom::combinator::flat_map(crate::util::nom_scale_compact_usize, move |num_elems| { nom::multi::many_m_n(num_elems, num_elems, decode_fragment(block_number_bytes)) }) } -fn decode_fragment<'a>( +fn decode_fragment<'a, E: nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], GrandpaWarpSyncResponseFragment<'a>> { +) -> impl nom::Parser<&'a [u8], Output = GrandpaWarpSyncResponseFragment<'a>, Error = E> { nom::combinator::map( - nom::sequence::tuple(( + ( nom::combinator::recognize(move |s| { header::decode_partial(s, block_number_bytes) .map(|(a, b)| (b, a)) @@ -120,7 +125,7 @@ fn decode_fragment<'a>( nom::Err::Failure(nom::error::make_error(s, nom::error::ErrorKind::Verify)) }) }), - )), + ), move |(scale_encoded_header, scale_encoded_justification)| { GrandpaWarpSyncResponseFragment { scale_encoded_header, diff --git a/lib/src/network/codec/identify.rs b/lib/src/network/codec/identify.rs index 007c801f05..d7cbeff1a5 100644 --- a/lib/src/network/codec/identify.rs +++ b/lib/src/network/codec/identify.rs @@ -126,7 +126,7 @@ pub fn decode_identify_response( IdentifyResponse<'_, vec::IntoIter<&[u8]>, vec::IntoIter<&str>>, DecodeIdentifyResponseError, > { - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[optional] protocol_version = 5 => protobuf::string_tag_decode, #[optional] agent_version = 6 => protobuf::string_tag_decode, @@ -137,7 +137,7 @@ pub fn decode_identify_response( }), ); - let decoded = match nom::Finish::finish(parser(response_bytes)) { + let decoded = match nom::Finish::finish(nom::Parser::parse(&mut parser, response_bytes)) { Ok((_, out)) => out, Err(_) => return Err(DecodeIdentifyResponseError::ProtobufDecode), }; diff --git a/lib/src/network/codec/kademlia.rs b/lib/src/network/codec/kademlia.rs index 9e58aff556..a428942486 100644 --- a/lib/src/network/codec/kademlia.rs +++ b/lib/src/network/codec/kademlia.rs @@ -41,7 +41,7 @@ pub fn build_find_node_request(peer_id: &[u8]) -> Vec { pub fn decode_find_node_response( response_bytes: &[u8], ) -> Result>)>, DecodeFindNodeResponseError> { - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[optional] response_ty = 1 => protobuf::enum_tag_decode, #[repeated(max = 1024)] peers = 8 => protobuf::message_tag_decode(protobuf::message_decode!{ @@ -51,7 +51,7 @@ pub fn decode_find_node_response( }), ); - let closer_peers = match nom::Finish::finish(parser(response_bytes)) { + let closer_peers = match nom::Finish::finish(nom::Parser::parse(&mut parser, response_bytes)) { Ok((_, out)) if out.response_ty.unwrap_or(0) == 4 => out.peers, Ok((_, _)) => return Err(DecodeFindNodeResponseError::BadResponseTy), Err(_) => { diff --git a/lib/src/network/codec/state_request.rs b/lib/src/network/codec/state_request.rs index 6b25b8ab6e..f596cdc3d5 100644 --- a/lib/src/network/codec/state_request.rs +++ b/lib/src/network/codec/state_request.rs @@ -109,13 +109,13 @@ pub fn build_state_request(config: StateRequest) -> impl Iterator Result<&[u8], DecodeStateResponseError> { - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[required] proof = 2 => protobuf::bytes_tag_decode, }), ); - let proof = match nom::Finish::finish(parser(response_bytes)) { + let proof = match nom::Finish::finish(nom::Parser::parse(&mut parser, response_bytes)) { Ok((_, proof)) => proof.proof, Err(_) => return Err(DecodeStateResponseError::ProtobufDecode), }; diff --git a/lib/src/network/codec/storage_call_proof.rs b/lib/src/network/codec/storage_call_proof.rs index f888089e2d..02df29c375 100644 --- a/lib/src/network/codec/storage_call_proof.rs +++ b/lib/src/network/codec/storage_call_proof.rs @@ -107,7 +107,7 @@ pub fn decode_storage_or_call_proof_response( // TODO: while the `proof` field is correctly optional, the `response` field isn't supposed to be optional; make it `#[required]` again once https://github.com/paritytech/substrate/pull/12732 has been merged and released - let mut parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( + let mut parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( nom::combinator::complete(protobuf::message_decode! { #[optional] response = field_num => protobuf::message_tag_decode(protobuf::message_decode!{ #[optional] proof = 2 => protobuf::bytes_tag_decode @@ -115,7 +115,7 @@ pub fn decode_storage_or_call_proof_response( }), ); - let proof = match nom::Finish::finish(parser(response_bytes)) { + let proof = match nom::Finish::finish(nom::Parser::parse(&mut parser, response_bytes)) { Ok((_, out)) => out.response.and_then(|r| r.proof), Err(_) => return Err(DecodeStorageCallProofResponseError::ProtobufDecode), }; diff --git a/lib/src/sync/para.rs b/lib/src/sync/para.rs index 3b082db45b..2196d46af6 100644 --- a/lib/src/sync/para.rs +++ b/lib/src/sync/para.rs @@ -77,9 +77,12 @@ pub fn decode_persisted_validation_data_return_value( scale_encoded: &[u8], block_number_bytes: usize, ) -> Result, Error> { - let res: Result<_, nom::Err>> = nom::combinator::all_consuming( - crate::util::nom_option_decode(persisted_validation_data(block_number_bytes)), - )(scale_encoded); + let res: Result<_, nom::Err>> = nom::Parser::parse( + &mut nom::combinator::all_consuming(crate::util::nom_option_decode( + persisted_validation_data(block_number_bytes), + )), + scale_encoded, + ); match res { Ok((_, data)) => Ok(data), Err(nom::Err::Error(err) | nom::Err::Failure(err)) => Err(Error(err.code)), @@ -112,14 +115,14 @@ pub struct PersistedValidationDataRef<'a> { /// `Nom` combinator that parses a [`PersistedValidationDataRef`]. fn persisted_validation_data<'a, E: nom::error::ParseError<&'a [u8]>>( block_number_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], PersistedValidationDataRef<'a>, E> { +) -> impl nom::Parser<&'a [u8], Output = PersistedValidationDataRef<'a>, Error = E> { nom::combinator::map( - nom::sequence::tuple(( + ( crate::util::nom_bytes_decode, crate::util::nom_varsize_number_decode_u64(block_number_bytes), nom::bytes::streaming::take(32u32), nom::number::streaming::le_u32, - )), + ), |(parent_head, relay_parent_number, relay_parent_storage_root, max_pov_size)| { PersistedValidationDataRef { parent_head, diff --git a/lib/src/transactions/validate.rs b/lib/src/transactions/validate.rs index 0145c410b6..eb301d17ba 100644 --- a/lib/src/transactions/validate.rs +++ b/lib/src/transactions/validate.rs @@ -220,7 +220,10 @@ pub const VALIDATION_FUNCTION_NAME: &str = "TaggedTransactionQueue_validate_tran pub fn decode_validate_transaction_return_value( scale_encoded: &[u8], ) -> Result, DecodeError> { - match nom::combinator::all_consuming(transaction_validity)(scale_encoded) { + match nom::Parser::parse( + &mut nom::combinator::all_consuming(transaction_validity), + scale_encoded, + ) { Ok((_, data)) => Ok(data), Err(_) => Err(DecodeError()), } @@ -231,135 +234,162 @@ pub fn decode_validate_transaction_return_value( fn transaction_validity( bytes: &[u8], ) -> nom::IResult<&[u8], Result> { - nom::error::context( - "transaction validity", - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), valid_transaction), - Ok, - ), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[1]), - transaction_validity_error, + nom::Parser::parse( + &mut nom::error::context( + "transaction validity", + nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + valid_transaction, + ), + Ok, ), - Err, - ), - )), - )(bytes) + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[1][..]), + transaction_validity_error, + ), + Err, + ), + )), + ), + bytes, + ) } fn valid_transaction(bytes: &[u8]) -> nom::IResult<&[u8], ValidTransaction> { - nom::error::context( - "valid transaction", - nom::combinator::map( - nom::sequence::tuple(( - nom::number::streaming::le_u64, - tags, - // TODO: maybe show by strong typing the fact that the provide tags are never empty - nom::combinator::verify(tags, |provides: &Vec>| !provides.is_empty()), - nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), - util::nom_bool_decode, - )), - |(priority, requires, provides, longevity, propagate)| ValidTransaction { - priority, - requires, - provides, - longevity, - propagate, - }, + nom::Parser::parse( + &mut nom::error::context( + "valid transaction", + nom::combinator::map( + ( + nom::number::streaming::le_u64, + tags, + // TODO: maybe show by strong typing the fact that the provide tags are never empty + nom::combinator::verify(tags, |provides: &Vec>| !provides.is_empty()), + nom::combinator::map_opt(nom::number::streaming::le_u64, NonZero::::new), + util::nom_bool_decode, + ), + |(priority, requires, provides, longevity, propagate)| ValidTransaction { + priority, + requires, + provides, + longevity, + propagate, + }, + ), ), - )(bytes) + bytes, + ) } fn transaction_validity_error(bytes: &[u8]) -> nom::IResult<&[u8], TransactionValidityError> { - nom::error::context( - "transaction validity error", - nom::branch::alt(( - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), invalid_transaction), - TransactionValidityError::Invalid, - ), - nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), unknown_transaction), - TransactionValidityError::Unknown, - ), - )), - )(bytes) + nom::Parser::parse( + &mut nom::error::context( + "transaction validity error", + nom::branch::alt(( + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[0][..]), + invalid_transaction, + ), + TransactionValidityError::Invalid, + ), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[1][..]), + unknown_transaction, + ), + TransactionValidityError::Unknown, + ), + )), + ), + bytes, + ) } fn invalid_transaction(bytes: &[u8]) -> nom::IResult<&[u8], InvalidTransaction> { - nom::error::context( - "invalid transaction", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - InvalidTransaction::Call - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - InvalidTransaction::Payment - }), - nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| { - InvalidTransaction::Future - }), - nom::combinator::map(nom::bytes::streaming::tag(&[3]), |_| { - InvalidTransaction::Stale - }), - nom::combinator::map(nom::bytes::streaming::tag(&[4]), |_| { - InvalidTransaction::BadProof - }), - nom::combinator::map(nom::bytes::streaming::tag(&[5]), |_| { - InvalidTransaction::AncientBirthBlock - }), - nom::combinator::map(nom::bytes::streaming::tag(&[6]), |_| { - InvalidTransaction::ExhaustsResources - }), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[7]), - nom::bytes::streaming::take(1u32), + nom::Parser::parse( + &mut nom::error::context( + "invalid transaction", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + InvalidTransaction::Call + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + InvalidTransaction::Payment + }), + nom::combinator::map(nom::bytes::streaming::tag(&[2][..]), |_| { + InvalidTransaction::Future + }), + nom::combinator::map(nom::bytes::streaming::tag(&[3][..]), |_| { + InvalidTransaction::Stale + }), + nom::combinator::map(nom::bytes::streaming::tag(&[4][..]), |_| { + InvalidTransaction::BadProof + }), + nom::combinator::map(nom::bytes::streaming::tag(&[5][..]), |_| { + InvalidTransaction::AncientBirthBlock + }), + nom::combinator::map(nom::bytes::streaming::tag(&[6][..]), |_| { + InvalidTransaction::ExhaustsResources + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[7][..]), + nom::bytes::streaming::take(1u32), + ), + |n: &[u8]| InvalidTransaction::Custom(n[0]), ), - |n: &[u8]| InvalidTransaction::Custom(n[0]), - ), - nom::combinator::map(nom::bytes::streaming::tag(&[8]), |_| { - InvalidTransaction::BadMandatory - }), - nom::combinator::map(nom::bytes::streaming::tag(&[9]), |_| { - InvalidTransaction::MandatoryDispatch - }), - )), - )(bytes) + nom::combinator::map(nom::bytes::streaming::tag(&[8][..]), |_| { + InvalidTransaction::BadMandatory + }), + nom::combinator::map(nom::bytes::streaming::tag(&[9][..]), |_| { + InvalidTransaction::MandatoryDispatch + }), + )), + ), + bytes, + ) } fn unknown_transaction(bytes: &[u8]) -> nom::IResult<&[u8], UnknownTransaction> { - nom::error::context( - "unknown transaction", - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| { - UnknownTransaction::CannotLookup - }), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| { - UnknownTransaction::NoUnsignedValidator - }), - nom::combinator::map( - nom::sequence::preceded( - nom::bytes::streaming::tag(&[2]), - nom::bytes::streaming::take(1u32), + nom::Parser::parse( + &mut nom::error::context( + "unknown transaction", + nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| { + UnknownTransaction::CannotLookup + }), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| { + UnknownTransaction::NoUnsignedValidator + }), + nom::combinator::map( + nom::sequence::preceded( + nom::bytes::streaming::tag(&[2][..]), + nom::bytes::streaming::take(1u32), + ), + |n: &[u8]| UnknownTransaction::Custom(n[0]), ), - |n: &[u8]| UnknownTransaction::Custom(n[0]), - ), - )), - )(bytes) + )), + ), + bytes, + ) } fn tags(bytes: &[u8]) -> nom::IResult<&[u8], Vec>> { - nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { - nom::multi::many_m_n( - num_elems, - num_elems, - nom::combinator::map( - nom::multi::length_data(crate::util::nom_scale_compact_usize), - |tag| tag.to_owned(), - ), - ) - })(bytes) + nom::Parser::parse( + &mut nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { + nom::multi::many_m_n( + num_elems, + num_elems, + nom::combinator::map( + nom::multi::length_data(crate::util::nom_scale_compact_usize), + |tag| tag.to_owned(), + ), + ) + }), + bytes, + ) } diff --git a/lib/src/trie.rs b/lib/src/trie.rs index baad4fb67a..0b58f8e3c3 100644 --- a/lib/src/trie.rs +++ b/lib/src/trie.rs @@ -274,10 +274,12 @@ pub fn ordered_root( let key = value_req .key() .collect::>(); - let value = match nom::combinator::all_consuming( - util::nom_scale_compact_usize::>, - )(&key) - { + let value = match nom::Parser::parse( + &mut nom::combinator::all_consuming( + util::nom_scale_compact_usize::>, + ), + &key, + ) { Ok((_, key)) => entries.get(key).map(move |v| (v, version)), Err(_) => None, }; diff --git a/lib/src/trie/proof_decode.rs b/lib/src/trie/proof_decode.rs index 81708233f6..502ec192d9 100644 --- a/lib/src/trie/proof_decode.rs +++ b/lib/src/trie/proof_decode.rs @@ -91,10 +91,15 @@ where // the function actually take less time than if it was a legitimate proof. let entries_by_merkle_value = { // TODO: don't use a Vec? - let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( - crate::util::nom_scale_compact_usize, - |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), - ))(config.proof.as_ref()) + let (_, decoded_proof) = nom::Parser::parse( + &mut nom::combinator::all_consuming(nom::combinator::flat_map( + crate::util::nom_scale_compact_usize, + |num_elems| { + nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode) + }, + )), + config.proof.as_ref(), + ) .map_err(|_: nom::Err>| Error::InvalidFormat)?; let entries_by_merkle_value = decoded_proof diff --git a/lib/src/util.rs b/lib/src/util.rs index 24941b3018..904375e69b 100644 --- a/lib/src/util.rs +++ b/lib/src/util.rs @@ -82,12 +82,12 @@ pub(crate) fn as_ref_iter( /// > **Note**: When using this function outside of a `nom` "context", you might have to explicit /// > the type of `E`. Use `nom::Err`. pub(crate) fn nom_option_decode<'a, O, E: nom::error::ParseError<&'a [u8]>>( - inner_decode: impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], O, E>, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], Option, E> { + inner_decode: impl nom::Parser<&'a [u8], Output = O, Error = E>, +) -> impl nom::Parser<&'a [u8], Output = Option, Error = E> { nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| None), + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| None), nom::combinator::map( - nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), inner_decode), + nom::sequence::preceded(nom::bytes::streaming::tag(&[1][..]), inner_decode), Some, ), )) @@ -97,7 +97,10 @@ pub(crate) fn nom_option_decode<'a, O, E: nom::error::ParseError<&'a [u8]>>( pub(crate) fn nom_bytes_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], &'a [u8], E> { - nom::multi::length_data(crate::util::nom_scale_compact_usize)(bytes) + nom::Parser::parse( + &mut nom::multi::length_data(crate::util::nom_scale_compact_usize), + bytes, + ) } /// Decodes a SCALE-encoded string. @@ -107,20 +110,26 @@ pub(crate) fn nom_string_decode< >( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], &'a str, E> { - nom::combinator::map_res( - nom::multi::length_data(crate::util::nom_scale_compact_usize), - str::from_utf8, - )(bytes) + nom::Parser::parse( + &mut nom::combinator::map_res( + nom::multi::length_data(crate::util::nom_scale_compact_usize), + str::from_utf8, + ), + bytes, + ) } /// Decodes a SCALE-encoded boolean. pub(crate) fn nom_bool_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], bool, E> { - nom::branch::alt(( - nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| false), - nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| true), - ))(bytes) + nom::Parser::parse( + &mut nom::branch::alt(( + nom::combinator::map(nom::bytes::streaming::tag(&[0][..]), |_| false), + nom::combinator::map(nom::bytes::streaming::tag(&[1][..]), |_| true), + )), + bytes, + ) } /// Decodes into a `u64` a SCALE-encoded number whose number of bytes isn't known at compile-time. @@ -128,7 +137,7 @@ pub(crate) fn nom_bool_decode<'a, E: nom::error::ParseError<&'a [u8]>>( /// Returns an error if the decoded number doesn't fit into a `u64`. pub(crate) fn nom_varsize_number_decode_u64<'a, E: nom::error::ParseError<&'a [u8]>>( num_bytes: usize, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], u64, E> { +) -> impl nom::Parser<&'a [u8], Output = u64, Error = E> { nom::combinator::map_opt( nom::bytes::streaming::take(num_bytes), move |slice: &[u8]| { diff --git a/lib/src/util/protobuf.rs b/lib/src/util/protobuf.rs index af47ac1536..2b13eabb49 100644 --- a/lib/src/util/protobuf.rs +++ b/lib/src/util/protobuf.rs @@ -112,18 +112,24 @@ pub(crate) fn delimited_tag_encode( pub(crate) fn tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], (u64, u8), E> { - nom::combinator::map(leb128::nom_leb128_u64, |num| { - let wire_ty = u8::try_from(num & 0b111).unwrap(); - let field = num >> 3; - (field, wire_ty) - })(bytes) + nom::Parser::parse( + &mut nom::combinator::map(leb128::nom_leb128_u64, |num| { + let wire_ty = u8::try_from(num & 0b111).unwrap(); + let field = num >> 3; + (field, wire_ty) + }), + bytes, + ) } /// Decodes a Protobuf tag of the given field number, and value where the data type is `uint32`. pub(crate) fn uint32_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], u32, E> { - nom::combinator::map_opt(varint_zigzag_tag_decode, |num| u32::try_from(num).ok())(bytes) + nom::Parser::parse( + &mut nom::combinator::map_opt(varint_zigzag_tag_decode, |num| u32::try_from(num).ok()), + bytes, + ) } /// Decodes a Protobuf tag and value where the data type is `bool`. @@ -134,13 +140,16 @@ pub(crate) fn uint32_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( pub(crate) fn bool_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], bool, E> { - nom::combinator::map(varint_zigzag_tag_decode, |n| { - // Note that booleans are undocumented. However, the official Java library interprets - // 0 as false and any other value as true. - // See - // or - n != 0 - })(bytes) + nom::Parser::parse( + &mut nom::combinator::map(varint_zigzag_tag_decode, |n| { + // Note that booleans are undocumented. However, the official Java library interprets + // 0 as false and any other value as true. + // See + // or + n != 0 + }), + bytes, + ) } /// Decodes a Protobuf tag and value where the data type is "enum". @@ -152,8 +161,8 @@ pub(crate) fn enum_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( /// Decodes a Protobuf tag and value where the data type is a sub-message. pub(crate) fn message_tag_decode<'a, O, E: nom::error::ParseError<&'a [u8]>>( - inner_message_parser: impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], O, E>, -) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], O, E> { + inner_message_parser: impl nom::Parser<&'a [u8], Output = O, Error = E>, +) -> impl nom::Parser<&'a [u8], Output = O, Error = E> { nom::combinator::map_parser(delimited_tag_decode, inner_message_parser) } @@ -161,61 +170,89 @@ pub(crate) fn message_tag_decode<'a, O, E: nom::error::ParseError<&'a [u8]>>( pub(crate) fn string_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], &'a str, E> { - nom::combinator::map_opt(delimited_tag_decode, |bytes| { - if bytes.len() > 2 * 1024 * 1024 * 1024 { - return None; - } - str::from_utf8(bytes).ok() - })(bytes) + nom::Parser::parse( + &mut nom::combinator::map_opt(delimited_tag_decode, |bytes| { + if bytes.len() > 2 * 1024 * 1024 * 1024 { + return None; + } + str::from_utf8(bytes).ok() + }), + bytes, + ) } /// Decodes a Protobuf tag and value where the data type is "bytes". pub(crate) fn bytes_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], &'a [u8], E> { - nom::combinator::verify(delimited_tag_decode, |bytes: &[u8]| { - bytes.len() <= 2 * 1024 * 1024 * 1024 - })(bytes) + nom::Parser::parse( + &mut nom::combinator::verify(delimited_tag_decode, |bytes: &[u8]| { + bytes.len() <= 2 * 1024 * 1024 * 1024 + }), + bytes, + ) } /// Decodes a Protobuf tag and value where the wire type is `varint` or "zigzag". pub(crate) fn varint_zigzag_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], u64, E> { - nom::sequence::preceded( - nom::combinator::verify(tag_decode, move |(_, ty)| *ty == 0), - leb128::nom_leb128_u64, - )(bytes) + nom::Parser::parse( + &mut nom::sequence::preceded( + nom::combinator::verify(tag_decode, move |(_, ty)| *ty == 0), + leb128::nom_leb128_u64, + ), + bytes, + ) } /// Decodes a Protobuf tag and value where the wire type is "delimited". pub(crate) fn delimited_tag_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], &'a [u8], E> { - nom::sequence::preceded( - nom::combinator::verify(tag_decode, move |(_, ty)| *ty == 2), - nom::multi::length_data(leb128::nom_leb128_usize), - )(bytes) + nom::Parser::parse( + &mut nom::sequence::preceded( + nom::combinator::verify(tag_decode, move |(_, ty)| *ty == 2), + nom::multi::length_data(leb128::nom_leb128_usize), + ), + bytes, + ) } /// Decodes a Protobuf tag and value and discards them. pub(crate) fn tag_value_skip_decode<'a, E: nom::error::ParseError<&'a [u8]>>( bytes: &'a [u8], ) -> nom::IResult<&'a [u8], (), E> { - nom::combinator::flat_map(tag_decode, |(_, wire_ty)| { - move |inner_bytes| match wire_ty { - 0 => nom::combinator::map(leb128::nom_leb128_u64, |_| ())(inner_bytes), - 5 => nom::combinator::map(nom::bytes::streaming::take(4u32), |_| ())(inner_bytes), - 1 => nom::combinator::map(nom::bytes::streaming::take(8u32), |_| ())(inner_bytes), - 2 => nom::combinator::map(nom::multi::length_data(leb128::nom_leb128_usize), |_| ())( - inner_bytes, - ), - _ => Err(nom::Err::Error(nom::error::ParseError::from_error_kind( - bytes, - nom::error::ErrorKind::Tag, - ))), - } - })(bytes) + nom::Parser::parse( + &mut nom::combinator::flat_map(tag_decode, |(_, wire_ty)| { + move |inner_bytes| match wire_ty { + 0 => nom::Parser::parse( + &mut nom::combinator::map(leb128::nom_leb128_u64, |_| ()), + inner_bytes, + ), + 5 => nom::Parser::parse( + &mut nom::combinator::map(nom::bytes::streaming::take(4u32), |_| ()), + inner_bytes, + ), + 1 => nom::Parser::parse( + &mut nom::combinator::map(nom::bytes::streaming::take(8u32), |_| ()), + inner_bytes, + ), + 2 => nom::Parser::parse( + &mut nom::combinator::map( + nom::multi::length_data(leb128::nom_leb128_usize), + |_| (), + ), + inner_bytes, + ), + _ => Err(nom::Err::Error(nom::error::ParseError::from_error_kind( + bytes, + nom::error::ErrorKind::Tag, + ))), + } + }), + bytes, + ) } /// Decodes a Protobuf message. @@ -264,7 +301,7 @@ pub(crate) fn tag_value_skip_decode<'a, E: nom::error::ParseError<&'a [u8]>>( /// # Example /// /// ```ignore -/// let _parser = nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>( +/// let _parser = nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>( /// nom::combinator::complete(protobuf::message_decode! { /// #[repeated(max = 4)] entries = 1 => protobuf::message_decode!{ /// #[required] state_root = 1 => protobuf::bytes_tag_decode(1), @@ -308,7 +345,7 @@ macro_rules! message_decode { let (_, (field_num, _wire_ty)) = $crate::util::protobuf::tag_decode(input)?; $(if field_num == $field_num { - let (rest, value) = nom::Parser::<&[u8], _, _>::parse(&mut $parser, input)?; + let (rest, value) = nom::Parser::<&[u8]>::parse(&mut $parser, input)?; if input == rest { // The field parser didn't consume any byte. This will lead diff --git a/lib/src/verify/body_only.rs b/lib/src/verify/body_only.rs index 1fe02fa2da..82d1641ce2 100644 --- a/lib/src/verify/body_only.rs +++ b/lib/src/verify/body_only.rs @@ -133,17 +133,17 @@ pub fn check_check_inherents_output(output: &[u8]) -> Result<(), InherentsOutput // on older runtimes that expect these values. For this reason, errors concerning `auraslot` // and `babeslot` are ignored. let parser = nom::sequence::preceded( - nom::sequence::tuple((crate::util::nom_bool_decode, crate::util::nom_bool_decode)), + (crate::util::nom_bool_decode, crate::util::nom_bool_decode), nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { nom::multi::fold_many_m_n( num_elems, num_elems, - nom::sequence::tuple(( + ( nom::combinator::map(nom::bytes::streaming::take(8u8), |b| { <[u8; 8]>::try_from(b).unwrap() }), crate::util::nom_bytes_decode, - )), + ), Vec::new, |mut errors, (module, error)| { if module != *b"auraslot" && module != *b"babeslot" { @@ -155,7 +155,10 @@ pub fn check_check_inherents_output(output: &[u8]) -> Result<(), InherentsOutput }), ); - match nom::combinator::all_consuming::<_, _, nom::error::Error<&[u8]>, _>(parser)(output) { + match nom::Parser::parse( + &mut nom::combinator::all_consuming::<_, nom::error::Error<&[u8]>, _>(parser), + output, + ) { Err(_err) => Err(InherentsOutputError::ParseFailure), Ok((_, errors)) => { if errors.is_empty() { diff --git a/wasm-node/rust/Cargo.toml b/wasm-node/rust/Cargo.toml index d89874db87..10916f0255 100644 --- a/wasm-node/rust/Cargo.toml +++ b/wasm-node/rust/Cargo.toml @@ -26,7 +26,7 @@ fnv = { version = "1.0.7", default-features = false } futures-lite = { version = "2.3.0", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.27", default-features = false } hashbrown = { version = "0.15.0", default-features = false } -nom = { version = "7.1.3", default-features = false } +nom = { version = "8.0.0", default-features = false } pin-project = "1.1.5" slab = { version = "0.4.8", default-features = false } smoldot = { version = "0.19.0", path = "../../lib", default-features = false } diff --git a/wasm-node/rust/src/platform.rs b/wasm-node/rust/src/platform.rs index fdce2371e0..8c32105c2b 100644 --- a/wasm-node/rust/src/platform.rs +++ b/wasm-node/rust/src/platform.rs @@ -972,12 +972,15 @@ pub(crate) fn connection_multi_stream_set_handshake_info( connection_id: u32, handshake_ty: Box<[u8]>, ) { - let (_, local_tls_certificate_sha256) = nom::sequence::preceded( - nom::bytes::streaming::tag::<_, _, nom::error::Error<&[u8]>>(&[0]), - nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { - <&[u8; 32]>::try_from(b).unwrap() - }), - )(&handshake_ty[..]) + let (_, local_tls_certificate_sha256) = nom::Parser::parse( + &mut nom::sequence::preceded( + nom::bytes::streaming::tag::<_, _, nom::error::Error<&[u8]>>(&[0][..]), + nom::combinator::map(nom::bytes::streaming::take(32u32), |b| { + <&[u8; 32]>::try_from(b).unwrap() + }), + ), + &handshake_ty[..], + ) .expect("invalid handshake type provided to connection_multi_stream_set_handshake_info"); let mut lock = STATE.try_lock().unwrap();