From 52b2b12fb5efe29fe7a80ecd0515ceeb17901e34 Mon Sep 17 00:00:00 2001 From: liuchengxu Date: Thu, 24 Oct 2024 17:16:55 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20subcoin-?= =?UTF-8?q?project/subcoin@aa2dfc41bf04f5fd3b0ef2be941ff0eae6b3c182=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- search-index.js | 2 +- .../subcoin_network-desc-0-.js | 2 +- src/subcoin_network/block_downloader.rs.html | 120 ++++-- .../block_downloader/blocks_first.rs.html | 138 +++--- .../block_downloader/headers_first.rs.html | 278 ++++++++---- src/subcoin_network/connection.rs.html | 12 +- src/subcoin_network/lib.rs.html | 26 +- src/subcoin_network/peer_manager.rs.html | 116 ++--- src/subcoin_network/peer_store.rs.html | 406 ++++++++++++++---- src/subcoin_network/sync.rs.html | 402 ++++++++++------- src/subcoin_network/worker.rs.html | 88 ++-- src/subcoin_node/cli/subcoin_params.rs.html | 6 +- src/subcoin_rpc/network.rs.html | 86 +++- subcoin_network/all.html | 2 +- subcoin_network/enum.Error.html | 9 +- subcoin_network/enum.PeerLatency.html | 81 ---- subcoin_network/enum.PeerSyncState.html | 34 +- subcoin_network/enum.SyncStrategy.html | 4 +- subcoin_network/index.html | 4 +- subcoin_network/sidebar-items.js | 2 +- subcoin_network/struct.Config.html | 2 +- subcoin_network/struct.Network.html | 8 +- subcoin_network/struct.PeerSync.html | 10 +- subcoin_network/sync/enum.PeerLatency.html | 11 - trait.impl/core/clone/trait.Clone.js | 2 +- trait.impl/core/cmp/trait.Eq.js | 2 +- trait.impl/core/cmp/trait.Ord.js | 3 +- trait.impl/core/cmp/trait.PartialEq.js | 2 +- trait.impl/core/cmp/trait.PartialOrd.js | 3 +- trait.impl/core/fmt/trait.Debug.js | 2 +- trait.impl/core/hash/trait.Hash.js | 3 + trait.impl/core/marker/trait.Copy.js | 2 +- trait.impl/core/marker/trait.Freeze.js | 2 +- trait.impl/core/marker/trait.Send.js | 2 +- .../core/marker/trait.StructuralPartialEq.js | 2 +- trait.impl/core/marker/trait.Sync.js | 2 +- trait.impl/core/marker/trait.Unpin.js | 2 +- .../panic/unwind_safe/trait.RefUnwindSafe.js | 2 +- .../panic/unwind_safe/trait.UnwindSafe.js | 2 +- trait.impl/serde/de/trait.Deserialize.js | 2 +- trait.impl/serde/ser/trait.Serialize.js | 2 +- 41 files changed, 1231 insertions(+), 655 deletions(-) delete mode 100644 subcoin_network/enum.PeerLatency.html delete mode 100644 subcoin_network/sync/enum.PeerLatency.html create mode 100644 trait.impl/core/hash/trait.Hash.js diff --git a/search-index.js b/search-index.js index 47d99b0d..280855ca 100644 --- a/search-index.js +++ b/search-index.js @@ -4,7 +4,7 @@ var searchIndex = new Map(JSON.parse('[\ ["sc_consensus_nakamoto",{"t":"PPPKFFGFFPPPGPGPFFFFGPPPPPPPPFPPPPNNNNNNNHONOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNOOOOO","n":["AlreadyInChain","BadDifficultyBits","BadVersion","BitcoinBlockImport","BitcoinBlockImporter","BlockImportQueue","BlockVerification","BlockVerifier","ChainParams","Client","Client","Codec","Error","Full","HeaderError","HeaderOnly","HeaderVerifier","ImportBlocks","ImportConfig","ImportManyBlocksResult","ImportStatus","Imported","InvalidBitcoinBlockHashDigest","InvalidProofOfWork","KnownBad","MissingBitcoinBlockHashDigest","MissingState","MultiplePreRuntimeDigests","None","SubstrateImportQueueVerifier","TimeTooOld","TooFarInFuture","UnknownParent","WrongEngine","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","bitcoin_import_queue","block_count","block_import_results","block_verification","blocks","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","csv_height","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","eq","equivalent","equivalent","equivalent","equivalent","equivalent","execute_block","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","has_valid_proof_of_work","import_block","import_block","import_blocks","imported","init","init","init","init","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into","into","into","into","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","is_unknown_parent","network","new","new","new","new","new","origin","params","results","script_flag_exceptions","segwit_height","source","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_possible_value","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","value_variants","verify","verify","verify_block","verify_script","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","expected","got","aux","block_hash","block_number"],"q":[[0,"sc_consensus_nakamoto"],[382,"sc_consensus_nakamoto::HeaderError"],[384,"sc_consensus_nakamoto::ImportStatus"],[387,"dyn_clone::sealed"],[388,"sc_consensus_nakamoto::import_queue"],[389,"sp_core::traits"],[390,"sc_consensus_nakamoto::block_import"],[391,"sc_consensus_nakamoto::verification::header_verify"],[392,"sc_consensus_nakamoto::chain_params"],[393,"sc_consensus_nakamoto::verification"],[394,"core::clone"],[395,"core::fmt"],[396,"sp_blockchain::error"],[397,"bitcoin::blockdata::block"],[398,"sp_runtime::traits"],[399,"sp_blockchain::backend"],[400,"sc_client_api::backend"],[401,"sp_consensus"],[402,"core::future::future"],[403,"alloc::boxed"],[404,"core::pin"],[405,"core::marker"],[406,"sc_client_api::client"],[407,"sp_api"],[408,"sc_consensus::block_import"],[409,"subcoin_primitives"],[410,"core::any"],[411,"alloc::sync"],[412,"alloc::rc"],[413,"prometheus::registry"],[414,"core::option"],[415,"bitcoin::network"],[416,"sc_consensus_nakamoto::verifier"],[417,"core::error"],[418,"clap_builder::builder::possible_value"],[419,"alloc::string"],[420,"core::result"]],"i":[11,21,21,0,0,0,0,0,0,21,22,22,0,14,0,14,0,0,0,0,0,11,22,21,11,22,11,22,14,0,21,21,11,22,9,10,11,12,13,14,15,0,8,4,10,13,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,9,10,11,12,13,14,15,9,10,11,12,13,14,15,9,10,11,12,13,14,14,15,12,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,14,14,14,14,14,14,10,10,11,12,13,4,8,21,21,14,22,22,33,9,50,10,11,12,13,4,8,21,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,9,6,33,4,8,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,11,10,33,9,50,12,15,13,12,8,12,12,21,22,9,10,11,12,13,14,15,14,21,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,33,9,50,10,11,12,13,4,8,21,14,15,22,14,9,50,15,10,33,9,50,10,11,12,13,4,8,21,14,15,22,60,60,61,61,61],"f":"``````````````````````````````````{{{b{c}}d}f{}}000000{{{b{c}}e}hjl}`{{{b{nh}}}A`}``{{{b{c}}}{{b{e}}}{}{}}000000000000{{{b{nc}}}{{b{ne}}}{}{}}000000000000{{{b{{Ab{ce}}}}}{{Ab{ce}}}{}{}}{{{b{Ad}}}Ad}{{{b{Af}}}Af}{{{b{Ah}}}Ah}{{{b{Aj}}}Aj}{{{b{Al}}}Al}{{{b{{An{ceg}}}}}{{An{ceg}}}B`B`B`}{{{b{c}}{b{ne}}}f{}{}}000000{{{b{c}}}f{}}0000000`{Bb{{b{c}}}{}}000000000000{Bb{{b{nc}}}{}}000000000000{Bbf}000000000000{{{b{Al}}{b{Al}}}Bd}{{{b{c}}{b{e}}}Bd{}{}}0000`{{{b{Ad}}{b{nBf}}}Bh}{{{b{Af}}{b{nBf}}}Bh}{{{b{Ah}}{b{nBf}}}Bh}{{{b{Aj}}{b{nBf}}}Bh}{{{b{h}}{b{nBf}}}Bh}{{{b{A`}}{b{nBf}}}Bh}{{{b{Bj}}{b{nBf}}}Bh}0{{{b{Al}}{b{nBf}}}Bh}{{{b{Bl}}{b{nBf}}}Bh}0{cc{}}000000000{BnBj}111{{{b{nc}}}{{b{ne}}}{}{}}000000000000{{{b{c}}}{{b{e}}}{}{}}000000000000{{{b{{Ab{ce}}}}{b{C`}}}BdCb{{Cd{c}}Cf}}{{{b{nl}}ChCj}{{D`{{Cn{Cl}}}}}}{{{b{n{Db{cgeik}}}}ChCj}{{D`{{Cn{Cl}}}}}Cb{{Dd{c}}DfDh}{{Cd{c}}{Dj{c}}{Dl{ce}}Cf{Dn{c}}{E`{c}}Df}{{Eb{c}}DfDh}{{Ed{c}}DfDh}}{{{b{h}}Aj}f}`{{}Bb}000000000000{ce{}{}}000000000000{{{Cn{c}}}{{Cn{Ef}}}{}}000000000000{{{Eh{c}}}{{Eh{Ef}}}{}}000000000000{{{Ej{c}}}{{Ej{Ef}}}{}}000000000000{{{b{Af}}}Bd}`{{{Eh{g}}iAd{Eh{El}}{F`{{b{En}}}}}{{Db{cgeik}}}Cb{{Dd{c}}}{{Cd{c}}{Dj{c}}Cf{Dn{c}}{Dl{ce}}{E`{c}}Df}{{Eb{c}}DfDh}{{Ed{c}}}}{{{Eh{c}}Ah}{{Ab{ec}}}{}{}}{{{Eh{c}}Fb}{{Fd{ec}}}{}{}}{FbAh}{{{Eh{c}}FbAl{Eh{El}}Bd}{{An{ecg}}}{}{}{}}`````{{{b{Bj}}}{{F`{{b{Ff}}}}}}{{{b{Bl}}}{{F`{{b{Ff}}}}}}{{{b{c}}}e{}{}}000000{{{b{Al}}}{{F`{Fh}}}}{{{b{c}}}Fj{}}0{c{{Fl{e}}}{}{}}0000000000000000000000000{{{b{c}}}Fn{}}000000000000{{{b{c}}}{{b{G`}}}{}}000000000000{ce{}{}}0000000000000000000000000{{}{{b{{Gb{Al}}}}}}{{{b{{Ab{ce}}}}{b{C`}}}{{Fl{GdBj}}}Cb{{Cd{c}}Cf}}{{{b{{Fd{ce}}}}{Gf{c}}}{{D`{{Cn{Cl}}}}}Cb{{Cd{c}}Cf}}{{{b{{An{cge}}}}Gd{b{Ch}}}{{Fl{f`}}}Cb{{Dd{c}}}{{Cd{c}}{Dl{ce}}Cf}}`4444444444444`````","D":"Mb","p":[[1,"reference"],[5,"Private",387],[1,"unit"],[5,"BlockImportQueue",0,388],[10,"SpawnEssentialNamed",389],[10,"BitcoinBlockImport",0,390],[0,"mut"],[5,"ImportManyBlocksResult",0,388],[5,"HeaderVerifier",0,391],[5,"ImportConfig",0,390],[6,"ImportStatus",0,390],[5,"ChainParams",0,392],[5,"ImportBlocks",0,388],[6,"BlockVerification",0,393],[5,"BlockVerifier",0,393],[10,"Clone",394],[1,"usize"],[1,"bool"],[5,"Formatter",395],[8,"Result",395],[6,"HeaderError",0],[6,"Error",0],[6,"Error",396],[5,"Header",397],[10,"Block",398],[10,"HeaderBackend",399],[10,"AuxStore",400],[5,"Block",397],[6,"BlockOrigin",401],[10,"Future",402],[5,"Box",403],[5,"Pin",404],[5,"BitcoinBlockImporter",0,390],[10,"Backend",400],[10,"Send",405],[10,"Sync",405],[10,"BlockBackend",406],[10,"StorageProvider",400],[10,"ProvideRuntimeApi",407],[10,"CallApiAt",407],[10,"BlockImport",408],[10,"BitcoinTransactionAdapter",409],[10,"Any",410],[5,"Arc",411],[5,"Rc",412],[10,"CoinStorageKey",409],[5,"Registry",413],[6,"Option",414],[6,"Network",415],[5,"SubstrateImportQueueVerifier",0,416],[10,"Error",417],[5,"PossibleValue",418],[5,"String",419],[6,"Result",420],[5,"TypeId",410],[1,"str"],[1,"slice"],[1,"u32"],[5,"BlockImportParams",408],[15,"BadDifficultyBits",382],[15,"Imported",384]],"r":[[3,390],[4,390],[5,388],[6,393],[7,393],[8,392],[16,391],[17,388],[18,390],[19,388],[20,390],[29,416],[41,388]],"b":[[147,"impl-Display-for-Error"],[148,"impl-Debug-for-Error"],[150,"impl-Display-for-Error"],[151,"impl-Debug-for-Error"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABoBEQAAAAAAAwAAAAsAAQAXAAAAGgAAABwAAAAiAAcALwAvAGAALACOAAoAowAAAMMAAADGAAwA4AAmABMBWgBvAQAAcgERAA=="}],\ ["subcoin_crypto",{"t":"HCFNNNNNNNNNNNNNNNNNNNN","n":["chacha20_block","muhash","MuHash3072","borrow","borrow_mut","clone","clone_into","clone_to_uninit","cmp","default","digest","eq","fmt","from","insert","into","new","partial_cmp","remove","to_owned","try_from","try_into","type_id"],"q":[[0,"subcoin_crypto"],[2,"subcoin_crypto::muhash"],[23,"alloc::vec"],[24,"core::cmp"],[25,"core::fmt"],[26,"core::option"],[27,"core::result"],[28,"core::any"]],"i":[0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],"f":"{{{f{{d{b}}}}{f{{d{b}}}}h}{{j{b}}}}``{{{f{c}}}{{f{e}}}{}{}}{{{f{lc}}}{{f{le}}}{}{}}{{{f{n}}}n}{{{f{c}}{f{le}}}A`{}{}}{{{f{c}}}A`{}}{{{f{n}}{f{n}}}Ab}{{}n}{{{f{n}}}{{j{b}}}}{{{f{n}}{f{n}}}Ad}{{{f{n}}{f{lAf}}}Ah}{cc{}}{{{f{ln}}{f{{Aj{b}}}}}A`}{ce{}{}}6{{{f{n}}{f{n}}}{{Al{Ab}}}}2{{{f{c}}}e{}{}}{c{{An{e}}}{}{}}0{{{f{c}}}B`{}}","D":"j","p":[[1,"u8"],[1,"array"],[1,"reference"],[1,"u32"],[5,"Vec",23],[0,"mut"],[5,"MuHash3072",2],[1,"unit"],[6,"Ordering",24],[1,"bool"],[5,"Formatter",25],[8,"Result",25],[1,"slice"],[6,"Option",26],[6,"Result",27],[5,"TypeId",28]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABIABAABAAAABAAJAA8AAAARAAYA"}],\ ["subcoin_informant",{"t":"H","n":["build"],"q":[[0,"subcoin_informant"],[1,"alloc::sync"],[2,"subcoin_network::network"],[3,"sp_runtime::traits"],[4,"sc_client_api"],[5,"sp_blockchain::header_metadata"],[6,"sc_client_api::client"],[7,"sp_blockchain::backend"],[8,"sc_client_api::backend"]],"i":[0],"f":"{{{b{e}}d}fh{{j{c}}{l{c}}{n{c}}{A`{c}}Ab}}","D":"d","p":[[5,"Arc",1],[5,"NetworkHandle",2],[1,"unit"],[10,"Block",3],[10,"UsageProvider",4],[10,"HeaderMetadata",5],[10,"BlockchainEvents",6],[10,"HeaderBackend",7],[10,"AuxStore",8]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAAAAAA="}],\ -["subcoin_network",{"t":"PPPPPPPFPPPPPPPGPPPPPPPPPPPIFPFFPPPPIGPPFGPPPPGPPGGPPPPPPPNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNOOOOONONOONOONNNNNNNNNONNOONNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOO","n":["Available","BadPong","BadProofOfWork","BitcoinEncoding","BitcoinIO","Blockchain","BlocksFirst","Config","Connect","ConnectionNotFound","ConnectionTimeout","Consensus","Discouraged","Downloading","DownloadingNew","Error","Failure","HandshakeTimeout","HeadersFirst","HeadersNotInAscendingOrder","IO","Idle","Importing","InvHasTooManyBlockItems","InvalidAddress","InvalidBootnode","Ipv4Only","Latency","Network","NetworkEventStreamError","NetworkHandle","NetworkStatus","NotFullNode","NotSegwitNode","Other","ParentOfFirstHeaderEntryNotFound","PeerId","PeerLatency","PeerNotFound","PeerShutdown","PeerSync","PeerSyncState","Ping","PingLatencyTooHigh","PingTimeout","ProtocolVersionTooLow","SendTransactionResult","SlowPeer","Success","SyncStatus","SyncStrategy","TooManyHeaders","TooManyInventoryItems","UnexpectedHandshakeState","UnexpectedPong","UnrequestedBlock","V4","V6","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","base_path","best_number","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","cmp","compare","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","enable_block_sync_on_startup","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","get_transaction","init","init","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into","into","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","ipv4_only","is_available","is_major_syncing","latency","listen_on","max_inbound_peers","max_outbound_peers","network","new","num_connected_peers","partial_cmp","peer_id","persistent_peer_latency_threshold","run","seednode_only","seednodes","send_transaction","serialize","serialize","serialize","serialize","serialize","serialize","source","start_block_sync","state","status","sync_peers","sync_status","sync_strategy","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_possible_value","to_string","total_bytes_inbound","total_bytes_outbound","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","value_variants","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","start","peers","peers","target","target"],"q":[[0,"subcoin_network"],[397,"subcoin_network::PeerSyncState"],[398,"subcoin_network::SyncStatus"],[402,"dyn_clone::sealed"],[403,"subcoin_network::network"],[404,"subcoin_network::sync"],[405,"core::cmp"],[406,"core::result"],[407,"serde::de"],[408,"core::fmt"],[409,"bitcoin::consensus::encode"],[410,"bitcoin_io::error"],[411,"sp_consensus::error"],[412,"sp_blockchain::error"],[413,"core::net::parser"],[414,"std::io::error"],[415,"bitcoin::blockdata::transaction"],[416,"core::option"],[417,"alloc::boxed"],[418,"core::any"],[419,"alloc::sync"],[420,"alloc::rc"],[421,"core::sync::atomic"],[422,"sc_consensus_nakamoto::import_queue"],[423,"sc_service::task_manager"],[424,"prometheus::registry"],[425,"sp_runtime::traits"],[426,"sp_blockchain::backend"],[427,"sc_client_api::backend"],[428,"serde::ser"],[429,"core::error"],[430,"alloc::vec"],[431,"clap_builder::builder::possible_value"],[432,"alloc::string"]],"i":[9,20,20,20,20,20,12,0,10,20,20,20,9,5,9,0,7,20,12,20,20,5,5,20,20,20,20,0,0,20,0,0,20,20,20,20,0,0,20,20,0,0,10,20,20,20,0,20,7,0,0,20,20,20,20,20,52,52,5,6,7,8,9,10,11,12,35,11,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,5,6,7,8,9,10,11,12,5,6,7,8,9,10,11,12,5,6,7,8,9,9,10,10,11,12,12,10,10,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,5,6,7,9,10,11,35,39,5,6,7,8,9,10,11,20,12,35,9,10,9,9,9,9,9,10,10,10,10,10,5,6,7,8,9,10,11,20,20,12,35,39,5,6,7,8,9,10,11,20,20,20,20,20,20,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,8,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,9,8,11,35,35,35,35,39,6,10,11,35,39,35,35,8,5,6,7,9,10,11,20,8,11,8,8,6,35,5,6,7,8,9,10,11,12,12,20,6,6,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,35,39,5,6,7,8,9,10,11,20,12,12,35,39,5,6,7,8,9,10,11,20,12,53,54,55,54,55],"f":"``````````````````````````````````````````````````````````{{{b{c}}d}f{}}0000000``{{{b{c}}}{{b{e}}}{}{}}0000000000{{{b{hc}}}{{b{he}}}{}{}}0000000000{{{b{j}}}j}{{{b{l}}}l}{{{b{n}}}n}{{{b{A`}}}A`}{{{b{Ab}}}Ab}{{{b{Ad}}}Ad}{{{b{Af}}}Af}{{{b{Ah}}}Ah}{{{b{c}}{b{he}}}f{}{}}0000000{{{b{c}}}f{}}0000000000{{{b{Ad}}{b{Ad}}}Aj}{{{b{c}}{b{e}}}Aj{}{}}{{}Ah}{Al{{b{c}}}{}}0000000000{Al{{b{hc}}}{}}0000000000{c{{An{j}}}B`}{c{{An{l}}}B`}{c{{An{n}}}B`}{c{{An{Ab}}}B`}{c{{An{Ad}}}B`}{c{{An{Af}}}B`}{Alf}0000000000`{{{b{Ab}}{b{Ab}}}Bb}{{{b{Ad}}{b{Ad}}}Bb}{{{b{c}}{b{e}}}Bb{}{}}000000000{{{b{j}}{b{hBd}}}Bf}{{{b{l}}{b{hBd}}}Bf}{{{b{n}}{b{hBd}}}Bf}{{{b{A`}}{b{hBd}}}Bf}{{{b{Ab}}{b{hBd}}}Bf}{{{b{Ad}}{b{hBd}}}Bf}{{{b{Af}}{b{hBd}}}Bf}{{{b{Bh}}{b{hBd}}}Bf}0{{{b{Ah}}{b{hBd}}}Bf}{cc{}}000000000{BjBh}{BlBh}{BnBh}{C`Bh}{CbBh}{CdBh}6{{{b{hc}}}{{b{he}}}{}{}}0000000000{{{b{c}}}{{b{e}}}{}{}}0000000000{{{b{A`}}Cf}{{Cj{Ch}}}}{{}Al}0000000000{ce{}{}}0000000000{{{Cl{c}}}{{Cl{Cn}}}{}}0000000000{{{D`{c}}}{{D`{Cn}}}{}}0000000000{{{Db{c}}}{{Db{Cn}}}{}}0000000000`{{{b{Ab}}}Bb}{{{b{A`}}}{{D`{Dd}}}}`````{{{D`{e}}DfDhDj{Cj{Dl}}}{{E`{{Dn{ce}}A`}}}Eb{{Ed{c}}Ef}}`{{{b{Ad}}{b{Ad}}}{{Cj{Aj}}}}``{{{Dn{ce}}}{{An{fBh}}}Eb{{Ed{c}}Ef}}``{{{b{A`}}Ch}n}{{{b{j}}c}AnEh}{{{b{l}}c}AnEh}{{{b{n}}c}AnEh}{{{b{Ab}}c}AnEh}{{{b{Ad}}c}AnEh}{{{b{Af}}c}AnEh}{{{b{Bh}}}{{Cj{{b{Ej}}}}}}{{{b{A`}}}Bb}`{{{b{A`}}}{{Cj{l}}}}{{{b{A`}}}{{El{Af}}}}``{{{b{c}}}e{}{}}0000000{{{b{Ah}}}{{Cj{En}}}}{{{b{c}}}F`{}}``{c{{An{e}}}{}{}}000000000000000000000{{{b{c}}}Fb{}}0000000000{{{b{c}}}{{b{Fd}}}{}}0000000000{ce{}{}}000000000000000000000{{}{{b{{Ff{Ah}}}}}}11111111111`````","D":"Lh","p":[[1,"reference"],[5,"Private",402],[1,"unit"],[0,"mut"],[6,"SyncStatus",0,403],[5,"NetworkStatus",0,403],[6,"SendTransactionResult",0,403],[5,"NetworkHandle",0,403],[6,"PeerSyncState",0,404],[6,"PeerLatency",0,404],[5,"PeerSync",0,404],[6,"SyncStrategy",0],[6,"Ordering",405],[1,"usize"],[6,"Result",406],[10,"Deserializer",407],[1,"bool"],[5,"Formatter",408],[8,"Result",408],[6,"Error",0],[6,"Error",409],[5,"Error",410],[6,"Error",411],[6,"Error",412],[5,"AddrParseError",413],[5,"Error",414],[5,"Txid",415],[5,"Transaction",415],[6,"Option",416],[5,"Box",417],[10,"Any",418],[5,"Arc",419],[5,"Rc",420],[5,"AtomicBool",421],[5,"Config",0],[5,"BlockImportQueue",422],[5,"SpawnTaskHandle",423],[5,"Registry",424],[5,"Network",0],[1,"tuple"],[10,"Block",425],[10,"HeaderBackend",426],[10,"AuxStore",427],[10,"Serializer",428],[10,"Error",429],[5,"Vec",430],[5,"PossibleValue",431],[5,"String",432],[5,"TypeId",418],[1,"str"],[1,"slice"],[8,"PeerId",0],[15,"DownloadingNew",397],[15,"Downloading",398],[15,"Importing",398]],"r":[[30,403],[31,403],[37,404],[40,404],[41,404],[46,403],[49,403]],"b":[[179,"impl-Display-for-Error"],[180,"impl-Debug-for-Error"],[192,"impl-From%3CError%3E-for-Error"],[193,"impl-From%3CError%3E-for-Error"],[194,"impl-From%3CError%3E-for-Error"],[195,"impl-From%3CError%3E-for-Error"],[196,"impl-From%3CAddrParseError%3E-for-Error"],[197,"impl-From%3CError%3E-for-Error"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAC4BFQACAAQACgACABIAAAAUAAEAGAADAB4AAAAhAAMAJwABACwAAgAwAAAANAAEADsABwBFAFoAoQAVAMEABQDfAAoA9QAgACABAAAnAQYANAEJAEABUgA="}],\ +["subcoin_network",{"t":"PPPPPPPFPPPPPPGPPPPPPPPPPPIFPFFPPPPIPPFGPPPGPPGGPPPPPPPPNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNOOOOONOOONOONNNNNNNNONNOONNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOO","n":["Available","BadPong","BadProofOfWork","BitcoinEncoding","BitcoinIO","Blockchain","BlocksFirst","Config","ConnectionNotFound","ConnectionTimeout","Consensus","Deprioritized","Downloading","DownloadingNew","Error","Failure","HandshakeTimeout","HeadersFirst","HeadersNotInAscendingOrder","IO","Idle","Importing","InvHasTooManyBlockItems","InvalidAddress","InvalidBootnode","Ipv4Only","Latency","Network","NetworkEventStreamError","NetworkHandle","NetworkStatus","NotFullNode","NotSegwitNode","Other","ParentOfFirstHeaderEntryNotFound","PeerId","PeerNotFound","PeerShutdown","PeerSync","PeerSyncState","PingLatencyTooHigh","PingTimeout","ProtocolVersionTooLow","SendTransactionResult","SlowPeer","Success","SyncStatus","SyncStrategy","TooManyHeaders","TooManyInventoryItems","UnexpectedHandshakeState","UnexpectedPong","UnreliablePeer","UnrequestedBlock","V4","V6","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","__clone_box","base_path","best_number","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","enable_block_sync_on_startup","eq","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_mut","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","from_ref","get_transaction","hash","init","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_arc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","into_any_rc","ipv4_only","is_available","is_major_syncing","latency","listen_on","max_inbound_peers","max_outbound_peers","network","new","num_connected_peers","peer_id","persistent_peer_latency_threshold","run","seednode_only","seednodes","send_transaction","serialize","serialize","serialize","serialize","serialize","source","start_block_sync","state","status","sync_peers","sync_status","sync_strategy","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_possible_value","to_string","total_bytes_inbound","total_bytes_outbound","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","type_name","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unchecked_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","value_variants","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","stalled_count","start","peers","peers","target","target"],"q":[[0,"subcoin_network"],[358,"subcoin_network::PeerSyncState"],[360,"subcoin_network::SyncStatus"],[364,"dyn_clone::sealed"],[365,"subcoin_network::network"],[366,"subcoin_network::sync"],[367,"core::result"],[368,"serde::de"],[369,"core::fmt"],[370,"sp_consensus::error"],[371,"std::io::error"],[372,"bitcoin_io::error"],[373,"bitcoin::consensus::encode"],[374,"core::net::parser"],[375,"sp_blockchain::error"],[376,"bitcoin::blockdata::transaction"],[377,"core::option"],[378,"core::hash"],[379,"alloc::boxed"],[380,"core::any"],[381,"alloc::sync"],[382,"alloc::rc"],[383,"core::sync::atomic"],[384,"sc_consensus_nakamoto::import_queue"],[385,"sc_service::task_manager"],[386,"prometheus::registry"],[387,"sp_runtime::traits"],[388,"sp_blockchain::backend"],[389,"sc_client_api::backend"],[390,"serde::ser"],[391,"core::error"],[392,"alloc::vec"],[393,"clap_builder::builder::possible_value"],[394,"alloc::string"]],"i":[9,18,18,18,18,18,11,0,18,18,18,9,5,9,0,7,18,11,18,18,5,5,18,18,18,18,0,0,18,0,0,18,18,18,18,0,18,18,0,0,18,18,18,0,18,7,0,0,18,18,18,18,18,18,51,51,5,6,7,8,9,10,11,34,10,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,5,6,7,8,9,10,11,5,6,7,8,9,10,11,5,6,7,8,9,9,10,11,11,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,5,6,7,9,10,34,38,5,6,7,8,9,10,18,11,34,9,9,9,9,9,9,5,6,7,8,9,10,18,18,11,34,38,5,6,7,8,9,10,18,18,18,18,18,18,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,8,9,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,9,8,10,34,34,34,34,38,6,10,34,38,34,34,8,5,6,7,9,10,18,8,10,8,8,6,34,5,6,7,8,9,10,11,11,18,6,6,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,34,38,5,6,7,8,9,10,18,11,11,34,38,5,6,7,8,9,10,18,11,52,53,54,55,54,55],"f":"````````````````````````````````````````````````````````{{{b{c}}d}f{}}000000``{{{b{c}}}{{b{e}}}{}{}}000000000{{{b{hc}}}{{b{he}}}{}{}}000000000{{{b{j}}}j}{{{b{l}}}l}{{{b{n}}}n}{{{b{A`}}}A`}{{{b{Ab}}}Ab}{{{b{Ad}}}Ad}{{{b{Af}}}Af}{{{b{c}}{b{he}}}f{}{}}000000{{{b{c}}}f{}}00000000{{}Af}{Ah{{b{c}}}{}}000000000{Ah{{b{hc}}}{}}000000000{c{{Aj{j}}}Al}{c{{Aj{l}}}Al}{c{{Aj{n}}}Al}{c{{Aj{Ab}}}Al}{c{{Aj{Ad}}}Al}{Ahf}000000000`{{{b{Ab}}{b{Ab}}}An}{{{b{c}}{b{e}}}An{}{}}0000{{{b{j}}{b{hB`}}}Bb}{{{b{l}}{b{hB`}}}Bb}{{{b{n}}{b{hB`}}}Bb}{{{b{A`}}{b{hB`}}}Bb}{{{b{Ab}}{b{hB`}}}Bb}{{{b{Ad}}{b{hB`}}}Bb}{{{b{Bd}}{b{hB`}}}Bb}0{{{b{Af}}{b{hB`}}}Bb}{cc{}}00000000{BfBd}{BhBd}{BjBd}{BlBd}{BnBd}{C`Bd}6{{{b{hc}}}{{b{he}}}{}{}}000000000{{{b{c}}}{{b{e}}}{}{}}000000000{{{b{A`}}Cb}{{Cf{Cd}}}}{{{b{Ab}}{b{hc}}}fCh}{{}Ah}000000000{ce{}{}}000000000{{{Cj{c}}}{{Cj{Cl}}}{}}000000000{{{Cn{c}}}{{Cn{Cl}}}{}}000000000{{{D`{c}}}{{D`{Cl}}}{}}000000000`{{{b{Ab}}}An}{{{b{A`}}}{{Cn{Db}}}}`````{{{Cn{e}}DdDfDh{Cf{Dj}}}{{Dn{{Dl{ce}}A`}}}E`{{Eb{c}}Ed}}```{{{Dl{ce}}}{{Aj{fBd}}}E`{{Eb{c}}Ed}}``{{{b{A`}}Cd}n}{{{b{j}}c}AjEf}{{{b{l}}c}AjEf}{{{b{n}}c}AjEf}{{{b{Ab}}c}AjEf}{{{b{Ad}}c}AjEf}{{{b{Bd}}}{{Cf{{b{Eh}}}}}}{{{b{A`}}}An}`{{{b{A`}}}{{Cf{l}}}}{{{b{A`}}}{{Ej{Ad}}}}``{{{b{c}}}e{}{}}000000{{{b{Af}}}{{Cf{El}}}}{{{b{c}}}En{}}``{c{{Aj{e}}}{}{}}0000000000000000000{{{b{c}}}F`{}}000000000{{{b{c}}}{{b{Fb}}}{}}000000000{ce{}{}}0000000000000000000{{}{{b{{Fd{Af}}}}}}1111111111``````","D":"Kl","p":[[1,"reference"],[5,"Private",364],[1,"unit"],[0,"mut"],[6,"SyncStatus",0,365],[5,"NetworkStatus",0,365],[6,"SendTransactionResult",0,365],[5,"NetworkHandle",0,365],[6,"PeerSyncState",0,366],[5,"PeerSync",0,366],[6,"SyncStrategy",0],[1,"usize"],[6,"Result",367],[10,"Deserializer",368],[1,"bool"],[5,"Formatter",369],[8,"Result",369],[6,"Error",0],[6,"Error",370],[5,"Error",371],[5,"Error",372],[6,"Error",373],[5,"AddrParseError",374],[6,"Error",375],[5,"Txid",376],[5,"Transaction",376],[6,"Option",377],[10,"Hasher",378],[5,"Box",379],[10,"Any",380],[5,"Arc",381],[5,"Rc",382],[5,"AtomicBool",383],[5,"Config",0],[5,"BlockImportQueue",384],[5,"SpawnTaskHandle",385],[5,"Registry",386],[5,"Network",0],[1,"tuple"],[10,"Block",387],[10,"HeaderBackend",388],[10,"AuxStore",389],[10,"Serializer",390],[10,"Error",391],[5,"Vec",392],[5,"PossibleValue",393],[5,"String",394],[5,"TypeId",380],[1,"str"],[1,"slice"],[8,"PeerId",0],[15,"Deprioritized",358],[15,"DownloadingNew",358],[15,"Downloading",360],[15,"Importing",360]],"r":[[29,365],[30,365],[38,366],[39,366],[43,365],[46,365]],"b":[[157,"impl-Display-for-Error"],[158,"impl-Debug-for-Error"],[169,"impl-From%3CError%3E-for-Error"],[170,"impl-From%3CError%3E-for-Error"],[171,"impl-From%3CError%3E-for-Error"],[172,"impl-From%3CError%3E-for-Error"],[173,"impl-From%3CAddrParseError%3E-for-Error"],[174,"impl-From%3CError%3E-for-Error"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAA4BFQACAAQACQACABEAAAATAAEAFwADAB0AAAAgAAMAJQABACkAAgAtAAAAMQAFADkABgBCAE4AkgAOAKoABQDGAAoA2wAdAAkBBQAVAQgAIAFGAGgBBAA="}],\ ["subcoin_node",{"t":"H","n":["run"],"q":[[0,"subcoin_node"],[1,"sc_cli::error"],[2,"subcoin_node::cli"]],"i":[0],"f":"{{}{{d{b}}}}","D":"d","p":[[1,"unit"],[8,"Result",1]],"r":[[0,2]],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAAAAAA="}],\ ["subcoin_primitives",{"t":"KKFKSKKGFPPPPPNNNMMHMMMMMMNNNNNNNNNNNNNNNNHNNNNNNNNNNNHHMNNNNNNNNNNNNNONNNNNNOOOHEMMMHNNNNNNNNNNNNNNNNNNNNNN","n":["BackendExt","BitcoinTransactionAdapter","BlockLocator","BlockLocatorProvider","CONFIRMATION_DEPTH","ClientExt","CoinStorageKey","HeaderError","IndexedBlock","InvalidBitcoinBlockHashDigest","InvalidBitcoinBlockHeader","MissingBitcoinBlockHashDigest","MissingBitcoinBlockHeader","MultiplePreRuntimeDigests","__clone_box","__clone_box","__clone_box","best_number","bitcoin_block_hash_for","bitcoin_genesis_tx","bitcoin_transaction_into_extrinsic","block_exists","block_hash","block_header","block_locator","block_number","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","convert_to_bitcoin_block","default","deref","deref","deref","deref_mut","deref_mut","deref_mut","drop","drop","drop","empty","extract_bitcoin_block_hash","extract_bitcoin_block_header","extrinsic_to_bitcoin_transaction","fmt","fmt","fmt","fmt","from","from","from","from_mut","from_mut","from_mut","from_ref","from_ref","from_ref","hash","init","init","init","into","into","into","latest_block","locator_hashes","number","raw_genesis_tx","runtime","storage_key","storage_prefix","substrate_block_hash_for","substrate_header_digest","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","unchecked_into","unchecked_into","unchecked_into","unique_saturated_into","unique_saturated_into","unique_saturated_into","vzip","vzip","vzip"],"q":[[0,"subcoin_primitives"],[108,"dyn_clone::sealed"],[109,"bitcoin::blockdata::block"],[110,"core::option"],[111,"alloc::vec"],[112,"bitcoin::blockdata::transaction"],[113,"core::ops::function"],[114,"core::result"],[115,"sp_runtime::traits"],[116,"core::fmt"],[117,"bitcoin::network"],[118,"sp_runtime::generic::digest"],[119,"alloc::string"],[120,"core::any"]],"i":[0,0,0,0,0,0,0,0,0,20,20,20,20,20,19,15,20,4,6,0,34,6,6,6,14,6,19,15,20,19,15,20,19,15,20,19,15,20,19,19,15,20,0,19,19,15,20,19,15,20,19,15,20,15,0,0,34,19,19,15,20,19,15,20,19,15,20,19,15,20,19,19,15,20,19,15,20,15,15,19,0,0,28,28,6,0,19,15,20,19,19,15,20,19,15,20,19,15,20,19,15,20,19,15,20,19,15,20],"f":"``````````````{{{b{c}}d}f{}}00{{{b{h}}}j}{{{b{l}}}{{A`{n}}}}{{}{{Ad{Ab}}}}{Af}{{{b{l}}n}Ah}{{{b{l}}j}{{A`{n}}}}{{{b{l}}n}{{A`{Aj}}}}{{{b{Al}}{A`{j}}c}An{{Bb{j}{{B`{{A`{n}}}}}}}}{{{b{l}}n}{{A`{j}}}}{{{b{c}}}{{b{e}}}{}{}}00{{{b{Bdc}}}{{b{Bde}}}{}{}}00{{{b{Bf}}}Bf}{{{b{An}}}An}{{{b{Bh}}}Bh}{{{b{c}}{b{Bde}}}f{}{}}00{{{b{c}}}f{}}000{c{{Bl{BjBh}}}Bn}{{}Bf}{C`{{b{c}}}{}}00{C`{{b{Bdc}}}{}}00{C`f}00{{}An}{b{{Bl{nBh}}}}{b{{Bl{AjBh}}}}{bAf}{{{b{Bf}}{b{BdCb}}}Cd}0{{{b{An}}{b{BdCb}}}Cd}{{{b{Bh}}{b{BdCb}}}Cd}{cc{}}00{{{b{Bdc}}}{{b{Bde}}}{}{}}00{{{b{c}}}{{b{e}}}{}{}}00`{{}C`}00{ce{}{}}00```{Cf{{Ad{Ab}}}}`{{{b{Ch}}Cjj}{{Ad{Ab}}}}{{{b{Ch}}}{{Cl{Ab}}}}{{{b{l}}n}A`}{{{b{Aj}}}Cn}{{{b{c}}}e{}{}}00{{{b{c}}}D`{}}{c{{Bl{e}}}{}{}}00000{{{b{c}}}Db{}}00999999999","D":"Eh","p":[[1,"reference"],[5,"Private",108],[1,"unit"],[10,"ClientExt",0],[1,"u32"],[10,"BackendExt",0],[5,"BlockHash",109],[6,"Option",110],[1,"u8"],[5,"Vec",111],[5,"Transaction",112],[1,"bool"],[5,"Header",109],[10,"BlockLocatorProvider",0],[5,"BlockLocator",0],[17,"Output"],[10,"Fn",113],[0,"mut"],[5,"IndexedBlock",0],[6,"HeaderError",0],[5,"Block",109],[6,"Result",114],[10,"Block",115],[1,"usize"],[5,"Formatter",116],[8,"Result",116],[6,"Network",117],[10,"CoinStorageKey",0],[5,"Txid",112],[1,"array"],[5,"Digest",118],[5,"String",119],[5,"TypeId",120],[10,"BitcoinTransactionAdapter",0]],"r":[],"b":[[57,"impl-Display-for-IndexedBlock"],[58,"impl-Debug-for-IndexedBlock"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAEAABwAKAAcAGwAPACwACgA6AAMASAACAFIAAABXABUA"}],\ ["subcoin_rpc",{"t":"FONNNNNNNNNNNNNNONONNNNNNN","n":["SubcoinRpc","blockchain","borrow","borrow_mut","deref","deref_mut","drop","from","from_mut","from_ref","init","into","into_any","into_any_arc","into_any_rc","merge_into","network","new","raw_transactions","try_from","try_into","type_id","type_name","unchecked_into","unique_saturated_into","vzip"],"q":[[0,"subcoin_rpc"],[26,"alloc::boxed"],[27,"core::any"],[28,"alloc::sync"],[29,"alloc::rc"],[30,"jsonrpsee_core::server::rpc_module"],[31,"jsonrpsee_core::error"],[32,"core::result"],[33,"sp_runtime::traits"],[34,"sp_blockchain::backend"],[35,"sc_client_api::client"],[36,"sc_client_api::backend"],[37,"subcoin_primitives"],[38,"core::marker"],[39,"subcoin_network::network"]],"i":[0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9],"f":"``{{{b{c}}}{{b{e}}}{}{}}{{{b{dc}}}{{b{de}}}{}{}}{f{{b{c}}}{}}{f{{b{dc}}}{}}{fh}{cc{}}45{{}f}{ce{}{}}{{{j{c}}}{{j{l}}}{}}{{{n{c}}}{{n{l}}}{}}{{{A`{c}}}{{A`{l}}}{}}{{{Ab{ceg}}{b{dAd}}}{{Ah{hAf}}}Aj{{Al{c}}{An{c}}B`}{{Bb{c}}BdBf}}`{{{n{e}}Bh}{{Ab{ceg}}}Aj{{Al{c}}{An{c}}B`}{{Bb{c}}BdBf}}`{c{{Ah{e}}}{}{}}0{{{b{c}}}Bj{}}{{{b{c}}}{{b{Bl}}}{}}888","D":"Ad","p":[[1,"reference"],[0,"mut"],[1,"usize"],[1,"unit"],[5,"Box",26],[10,"Any",27],[5,"Arc",28],[5,"Rc",29],[5,"SubcoinRpc",0],[5,"Methods",30],[6,"RegisterMethodError",31],[6,"Result",32],[10,"Block",33],[10,"HeaderBackend",34],[10,"BlockBackend",35],[10,"AuxStore",36],[10,"BitcoinTransactionAdapter",37],[10,"Send",38],[10,"Sync",38],[5,"NetworkHandle",39],[5,"TypeId",27],[1,"str"]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABAABQAAAAAAAwAEAAsAAAANAAIAFAAGAA=="}],\ diff --git a/search.desc/subcoin_network/subcoin_network-desc-0-.js b/search.desc/subcoin_network/subcoin_network-desc-0-.js index 445ea8fd..f9b0bb0b 100644 --- a/search.desc/subcoin_network/subcoin_network-desc-0-.js +++ b/search.desc/subcoin_network/subcoin_network-desc-0-.js @@ -1 +1 @@ -searchState.loadedDescShard("subcoin_network", 0, "Bitcoin Network\nAvailable for sync requests.\nDownload the full blocks (both headers and bodies) in …\nNetwork configuration.\nConnection latency.\nThe peer has been discouraged due to syncing from this …\nThe node is downloading blocks from peers.\nActively downloading new blocks, starting from the given …\nNetwork error type.\nAn error occurred during the transaction submission.\nDownload the headers first, followed by the block bodies.\nThe node is idle and not currently major syncing.\nThe node is importing downloaded blocks into the local …\nPeer latency in milliseconds.\nRepresents the Subcoin network component.\nA handle for interacting with the network worker.\nRepresents the status of network.\nIdentifies a peer.\nLetency of the peer.\nContains all the data about a Peer that we are trying to …\nThe state of syncing between a Peer and ourselves.\nAverage ping latency.\nRepresents the result of submitting a transaction to the …\nTransaction was submitted successfully.\nRepresents the sync status of node.\nRepresents the strategy for block syncing.\nAn IPv4 socket address.\nAn IPv6 socket address.\nNode base path.\nThe number of the best block that we’ve seen for this …\nWhether to enable the block sync on startup.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nRetrieves a transaction by its Txid.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nWhether to accept the peer in ipv4 only.\nReturns true if the peer is available for syncing.\nReturns a flag indicating whether the node is actively …\nLatency of connection to this peer.\nSpecify the local listen address.\nMaximum number of inbound peer connections.\nMaximum number of outbound peer connections.\nBitcoin network type.\nConstructs a new instance of Network.\nThe number of peers currently connected to the node.\nPeer id of this peer.\nPersistent peer latency threshold in milliseconds (ms).\nStarts the network.\nWhether to connect to the seednode only.\nList of seednodes.\nSends a transaction to the network.\nStarts the block sync in chain sync component.\nThe state of syncing this peer is in for us, generally …\nProvides high-level status information about network.\nReturns the currently syncing peers.\nCurrent sync status of the node.\nMajor sync strategy.\nThe total number of bytes received from the network.\nThe total number of bytes sent to the network.") \ No newline at end of file +searchState.loadedDescShard("subcoin_network", 0, "Bitcoin Network\nAvailable for sync requests.\nDownload the full blocks (both headers and bodies) in …\nNetwork configuration.\nThe peer has been deprioritized due to past syncing issues …\nThe node is downloading blocks from peers.\nActively downloading new blocks, starting from the given …\nNetwork error type.\nAn error occurred during the transaction submission.\nDownload the headers first, followed by the block bodies.\nThe node is idle and not currently major syncing.\nThe node is importing downloaded blocks into the local …\nPeer latency in milliseconds.\nRepresents the Subcoin network component.\nA handle for interacting with the network worker.\nRepresents the status of network.\nIdentifies a peer.\nContains all the data about a Peer that we are trying to …\nThe state of syncing between a Peer and ourselves.\nRepresents the result of submitting a transaction to the …\nTransaction was submitted successfully.\nRepresents the sync status of node.\nRepresents the strategy for block syncing.\nAn IPv4 socket address.\nAn IPv6 socket address.\nNode base path.\nThe number of the best block that we’ve seen for this …\nWhether to enable the block sync on startup.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a mutable reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nGet a reference to the inner from the outer.\nRetrieves a transaction by its Txid.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nWhether to accept the peer in ipv4 only.\nReturns true if the peer is available for syncing.\nReturns a flag indicating whether the node is actively …\nLatency of connection to this peer.\nSpecify the local listen address.\nMaximum number of inbound peer connections.\nMaximum number of outbound peer connections.\nBitcoin network type.\nConstructs a new instance of Network.\nThe number of peers currently connected to the node.\nPeer id of this peer.\nPersistent peer latency threshold in milliseconds (ms).\nStarts the network.\nWhether to connect to the seednode only.\nList of seednodes.\nSends a transaction to the network.\nStarts the block sync in chain sync component.\nThe state of syncing this peer is in for us, generally …\nProvides high-level status information about network.\nReturns the currently syncing peers.\nCurrent sync status of the node.\nMajor sync strategy.\nThe total number of bytes received from the network.\nThe total number of bytes sent to the network.\nNumber of times the peer has stalled.") \ No newline at end of file diff --git a/src/subcoin_network/block_downloader.rs.html b/src/subcoin_network/block_downloader.rs.html index 238016a0..5cc38f54 100644 --- a/src/subcoin_network/block_downloader.rs.html +++ b/src/subcoin_network/block_downloader.rs.html @@ -292,6 +292,42 @@ 292 293 294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330
mod blocks_first;
 mod headers_first;
 
@@ -299,10 +335,13 @@
 pub use self::headers_first::HeadersFirstDownloader;
 
 use crate::orphan_blocks_pool::OrphanBlocksPool;
+use crate::peer_store::PeerStore;
+use crate::PeerId;
 use bitcoin::{Block as BitcoinBlock, BlockHash};
 use sc_consensus::BlockImportError;
 use sc_consensus_nakamoto::ImportManyBlocksResult;
 use std::collections::{HashMap, HashSet};
+use std::sync::Arc;
 use std::time::{Duration, Instant};
 
 /// Interval for logging when the block import queue is too busy.
@@ -341,6 +380,20 @@
     }
 }
 
+#[derive(Debug, Clone, Copy)]
+enum ImportQueueStatus {
+    /// Queue is ready to accept more blocks for import.
+    Ready,
+    /// The queue is overloaded and cannot accept more blocks at the moment.
+    Overloaded,
+}
+
+impl ImportQueueStatus {
+    fn is_overloaded(&self) -> bool {
+        matches!(self, Self::Overloaded)
+    }
+}
+
 /// Manages the of blocks downloaded from the Bitcoin network.
 ///
 /// This struct keeps track of:
@@ -352,7 +405,7 @@
 /// [`BlockDownloadManager`] is designed to be used in both Blocks-First and
 /// Headers-First sync strategies, providing a common component for managing
 /// the state of blocks during the sync process.
-#[derive(Debug, Clone)]
+#[derive(Clone)]
 pub(crate) struct BlockDownloadManager {
     /// A set of block hashes that have been requested from the network.
     ///
@@ -377,14 +430,16 @@
     /// when the results of processed blocks are notified. It helps track
     /// the most recent activity related to block processing.
     last_progress_time: Instant,
-    /// Whether there are too many blocks in the queue.
-    import_queue_is_overloaded: bool,
+    /// Import queue status.
+    queue_status: ImportQueueStatus,
     /// Last time the log of too many blocks in the queue was printed.
     last_overloaded_queue_log_time: Option<Instant>,
+    /// Peer store.
+    peer_store: Arc<dyn PeerStore>,
 }
 
 impl BlockDownloadManager {
-    fn new() -> Self {
+    fn new(peer_store: Arc<dyn PeerStore>) -> Self {
         Self {
             requested_blocks: HashSet::new(),
             downloaded_blocks: Vec::new(),
@@ -393,8 +448,9 @@
             best_queued_number: 0u32,
             orphan_blocks_pool: OrphanBlocksPool::new(),
             last_progress_time: Instant::now(),
-            import_queue_is_overloaded: false,
+            queue_status: ImportQueueStatus::Ready,
             last_overloaded_queue_log_time: None,
+            peer_store,
         }
     }
 
@@ -411,7 +467,7 @@
     ///   increases, resulting in longer network response times for block retrieval.
     ///
     /// The timeout values are configurated arbitrarily.
-    fn is_stalled(&self) -> bool {
+    fn is_stalled(&self, peer_id: PeerId) -> bool {
         let stall_timeout = match self.best_queued_number {
             0..300_000 => 60,        // Standard timeout, 1 minute
             300_000..600_000 => 120, // Extended timeout, 2 minutes
@@ -419,7 +475,13 @@
             _ => 300,
         };
 
-        self.last_progress_time.elapsed().as_secs() > stall_timeout
+        let stalled = self.last_progress_time.elapsed().as_secs() > stall_timeout;
+
+        if stalled {
+            self.peer_store.record_failure(peer_id);
+        }
+
+        stalled
     }
 
     fn block_exists(&self, block_hash: BlockHash) -> bool {
@@ -442,36 +504,38 @@
     }
 
     /// Checks if the import queue is overloaded and updates the internal state.
-    fn update_and_check_queue_status(&mut self, best_number: u32) -> bool {
+    fn evaluate_queue_status(&mut self, best_number: u32) -> ImportQueueStatus {
         // Maximum number of pending blocks in the import queue.
         let max_queued_blocks = match best_number {
             0..=100_000 => 8192,
             100_001..=200_000 => 4096,
             200_001..=300_000 => 2048,
+            300_001..=600_000 => 1024,
             _ => 512,
         };
 
         let queued_blocks = self.best_queued_number - best_number;
 
-        let import_queue_is_overloaded = queued_blocks > max_queued_blocks;
+        if queued_blocks > max_queued_blocks {
+            self.queue_status = ImportQueueStatus::Overloaded;
 
-        if import_queue_is_overloaded
-            && self
+            if self
                 .last_overloaded_queue_log_time
                 .map(|last_time| last_time.elapsed() > BUSY_QUEUE_LOG_INTERVAL)
                 .unwrap_or(true)
-        {
-            tracing::debug!(
-                best_number,
-                best_queued_number = self.best_queued_number,
-                "⏸️ Pausing download: too many blocks ({queued_blocks}) in the queue",
-            );
-            self.last_overloaded_queue_log_time.replace(Instant::now());
+            {
+                tracing::debug!(
+                    best_number,
+                    best_queued_number = self.best_queued_number,
+                    "⏸️ Pausing download: too many blocks ({queued_blocks}) in the queue",
+                );
+                self.last_overloaded_queue_log_time.replace(Instant::now());
+            }
+        } else {
+            self.queue_status = ImportQueueStatus::Ready;
         }
 
-        self.import_queue_is_overloaded = import_queue_is_overloaded;
-
-        self.import_queue_is_overloaded
+        self.queue_status
     }
 
     fn reset(&mut self) {
@@ -482,7 +546,7 @@
         self.best_queued_number = 0u32;
         self.orphan_blocks_pool.clear();
         self.last_progress_time = Instant::now();
-        self.import_queue_is_overloaded = false;
+        self.queue_status = ImportQueueStatus::Ready;
     }
 
     /// Checks if there are blocks ready to be imported.
@@ -547,8 +611,14 @@
             .unzip()
     }
 
-    /// Add the block the queue that is ready to be imported.
-    fn add_block(&mut self, block_number: u32, block_hash: BlockHash, block: BitcoinBlock) {
+    /// Add the block that is ready to be imported.
+    fn add_block(
+        &mut self,
+        block_number: u32,
+        block_hash: BlockHash,
+        block: BitcoinBlock,
+        from: PeerId,
+    ) {
         let mut insert_block = |block_number, block_hash, block| {
             self.downloaded_blocks.push(block);
             self.queued_blocks.insert(block_number, block_hash);
@@ -568,6 +638,8 @@
                 insert_block(number, hash, child_block);
             }
         }
+
+        self.peer_store.record_block_download(from);
     }
 
     fn add_orphan_block(&mut self, block_hash: BlockHash, orphan_block: BitcoinBlock) {
diff --git a/src/subcoin_network/block_downloader/blocks_first.rs.html b/src/subcoin_network/block_downloader/blocks_first.rs.html
index da677359..f468dc3d 100644
--- a/src/subcoin_network/block_downloader/blocks_first.rs.html
+++ b/src/subcoin_network/block_downloader/blocks_first.rs.html
@@ -497,7 +497,28 @@
 497
 498
 499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
 
use crate::block_downloader::BlockDownloadManager;
+use crate::peer_store::PeerStore;
 use crate::sync::{LocatorRequest, SyncAction, SyncRequest};
 use crate::{Error, PeerId, SyncStatus};
 use bitcoin::hashes::Hash;
@@ -518,8 +539,9 @@
 // request is [1, 500] when doing the initial sync.
 const MAX_GET_BLOCKS_RESPONSE: u32 = 500;
 
-#[derive(Debug, Clone)]
-enum DownloadState {
+/// Download state.
+#[derive(Debug, Clone)]
+enum State {
     /// Downloading not started yet.
     Idle,
     /// Restarting the download process.
@@ -538,18 +560,19 @@
 }
 
 /// Download blocks using the Blocks-First strategy.
-#[derive(Debug, Clone)]
+#[derive(Clone)]
 pub struct BlocksFirstDownloader<Block, Client> {
     client: Arc<Client>,
     peer_id: PeerId,
     /// The final block number we are targeting when the download is complete.
     target_block_number: u32,
-    download_state: DownloadState,
+    state: State,
     download_manager: BlockDownloadManager,
+    downloaded_blocks_count: usize,
     last_locator_start: u32,
     pending_block_requests: Vec<Inventory>,
     /// Number of blocks' data requested but not yet received.
-    requested_blocks_count: usize,
+    inflight_blocks_count: usize,
     _phantom: PhantomData<Block>,
 }
 
@@ -558,16 +581,22 @@
     Block: BlockT,
     Client: HeaderBackend<Block> + AuxStore,
 {
-    pub(crate) fn new(client: Arc<Client>, peer_id: PeerId, peer_best: u32) -> (Self, SyncRequest) {
+    pub(crate) fn new(
+        client: Arc<Client>,
+        peer_id: PeerId,
+        peer_best: u32,
+        peer_store: Arc<dyn PeerStore>,
+    ) -> (Self, SyncRequest) {
         let mut blocks_first_sync = Self {
             peer_id,
             client,
             target_block_number: peer_best,
-            download_state: DownloadState::Idle,
-            download_manager: BlockDownloadManager::new(),
+            state: State::Idle,
+            download_manager: BlockDownloadManager::new(peer_store),
+            downloaded_blocks_count: 0,
             last_locator_start: 0u32,
             pending_block_requests: Vec::new(),
-            requested_blocks_count: 0,
+            inflight_blocks_count: 0,
             _phantom: Default::default(),
         };
 
@@ -577,7 +606,7 @@
     }
 
     pub(crate) fn sync_status(&self) -> SyncStatus {
-        if self.download_manager.import_queue_is_overloaded {
+        if self.download_manager.queue_status.is_overloaded() {
             SyncStatus::Importing {
                 target: self.target_block_number,
                 peers: vec![self.peer_id],
@@ -590,13 +619,18 @@
         }
     }
 
-    pub(crate) fn sync_peer(&self) -> PeerId {
-        self.peer_id
+    pub(crate) fn replaceable_sync_peer(&self) -> Option<PeerId> {
+        if self.downloaded_blocks_count > 0 {
+            None
+        } else {
+            Some(self.peer_id)
+        }
     }
 
-    pub(crate) fn update_sync_peer(&mut self, peer_id: PeerId, target_block_number: u32) {
+    pub(crate) fn replace_sync_peer(&mut self, peer_id: PeerId, target_block_number: u32) {
         self.peer_id = peer_id;
         self.target_block_number = target_block_number;
+        self.downloaded_blocks_count = 0;
     }
 
     pub(crate) fn download_manager(&mut self) -> &mut BlockDownloadManager {
@@ -604,32 +638,35 @@
     }
 
     pub(crate) fn on_tick(&mut self) -> SyncAction {
-        if matches!(self.download_state, DownloadState::Restarting) {
+        if matches!(self.state, State::Restarting) {
             return SyncAction::Request(self.prepare_blocks_request());
         }
 
-        if self.download_manager.import_queue_is_overloaded {
-            if self
+        let best_number = self.client.best_number();
+
+        if self.download_manager.queue_status.is_overloaded() {
+            let still_overloaded = self
                 .download_manager
-                .update_and_check_queue_status(self.client.best_number())
-            {
+                .evaluate_queue_status(best_number)
+                .is_overloaded();
+            if still_overloaded {
                 return SyncAction::None;
             } else {
                 return SyncAction::Request(self.prepare_blocks_request());
             }
         }
 
-        if !self.pending_block_requests.is_empty() && self.requested_blocks_count == 0 {
+        if !self.pending_block_requests.is_empty() && self.inflight_blocks_count == 0 {
             let block_data_request = std::mem::take(&mut self.pending_block_requests);
             return self.truncate_and_prepare_block_data_request(block_data_request);
         }
 
-        if self.client.best_number() == self.target_block_number {
-            self.download_state = DownloadState::Completed;
+        if best_number == self.target_block_number {
+            self.state = State::Completed;
             return SyncAction::SwitchToIdle;
         }
 
-        if self.download_manager.is_stalled() {
+        if self.download_manager.is_stalled(self.peer_id) {
             return SyncAction::RestartSyncWithStalledPeer(self.peer_id);
         }
 
@@ -638,12 +675,13 @@
 
     pub(crate) fn restart(&mut self, new_peer: PeerId, peer_best: u32) {
         self.peer_id = new_peer;
+        self.downloaded_blocks_count = 0;
         self.target_block_number = peer_best;
         self.last_locator_start = 0u32;
         self.download_manager.reset();
-        self.download_state = DownloadState::Restarting;
+        self.state = State::Restarting;
         self.pending_block_requests.clear();
-        self.requested_blocks_count = 0;
+        self.inflight_blocks_count = 0;
     }
 
     // Handle `inv` message.
@@ -666,7 +704,7 @@
                 ?from,
                 "Received inv with more than {MAX_GET_BLOCKS_RESPONSE} block entries"
             );
-            self.download_state = DownloadState::Disconnecting;
+            self.state = State::Disconnecting;
             return SyncAction::Disconnect(self.peer_id, Error::InvHasTooManyBlockItems);
         }
 
@@ -706,13 +744,13 @@
             self.pending_block_requests = block_data_request.split_off(max_request_size);
         }
 
-        self.requested_blocks_count = block_data_request.len();
+        self.inflight_blocks_count = block_data_request.len();
 
         tracing::debug!(
             from = ?self.peer_id,
             pending_block_data_request = self.pending_block_requests.len(),
             "📦 Downloading {} blocks",
-            self.requested_blocks_count,
+            self.inflight_blocks_count,
         );
 
         SyncAction::Request(SyncRequest::Data(block_data_request, self.peer_id))
@@ -724,8 +762,8 @@
             return SyncAction::None;
         }
 
-        let last_get_blocks_target = match &self.download_state {
-            DownloadState::DownloadingNew(range) => range.end - 1,
+        let last_get_blocks_target = match &self.state {
+            State::DownloadingNew(range) => range.end - 1,
             state => {
                 tracing::debug!(
                     ?state,
@@ -762,9 +800,10 @@
             tracing::trace!("Add pending block #{block_number},{block_hash}");
 
             self.download_manager
-                .add_block(block_number, block_hash, block);
+                .add_block(block_number, block_hash, block, from);
 
-            self.requested_blocks_count -= 1;
+            self.inflight_blocks_count -= 1;
+            self.downloaded_blocks_count += 1;
 
             match block_number.cmp(&last_get_blocks_target) {
                 CmpOrdering::Less => {
@@ -778,10 +817,10 @@
                             target_block_number = self.target_block_number,
                             "Received block #{block_number},{block_hash} higher than the target block"
                         );
-                        self.download_state = DownloadState::Completed;
+                        self.state = State::Completed;
                         SyncAction::SwitchToIdle
                     } else {
-                        self.download_state = DownloadState::Disconnecting;
+                        self.state = State::Disconnecting;
                         SyncAction::Disconnect(
                             self.peer_id,
                             Error::Other(format!(
@@ -797,25 +836,19 @@
                     // No more new blocks request as there are enough ongoing blocks in the queue.
                     if self
                         .download_manager
-                        .update_and_check_queue_status(best_number)
+                        .evaluate_queue_status(best_number)
+                        .is_overloaded()
                     {
                         return SyncAction::None;
                     }
 
                     let best_queued_number = self.download_manager.best_queued_number;
 
-                    tracing::debug!(
-                        best_number,
-                        best_queued_number,
-                        "Last getblocks finished, requesting more blocks",
-                    );
-
                     let end = self
                         .target_block_number
                         .min(best_queued_number + MAX_GET_BLOCKS_RESPONSE);
 
-                    self.download_state =
-                        DownloadState::DownloadingNew(best_queued_number + 1..end + 1);
+                    self.state = State::DownloadingNew(best_queued_number + 1..end + 1);
 
                     let BlockLocator { locator_hashes, .. } = self
                         .client
@@ -823,11 +856,16 @@
                             self.download_manager.queued_blocks.block_hash(height)
                         });
 
-                    // Last `getblocks` finished, fetch more blocks by sending a new `getblocks` request.
-                    SyncAction::Request(SyncRequest::Blocks(LocatorRequest {
+                    tracing::debug!(
+                        best_number,
+                        best_queued_number,
+                        "Last `getblocks` finished, fetching more blocks",
+                    );
+
+                    SyncAction::Request(SyncRequest::Blocks(LocatorRequest {
                         locator_hashes,
                         stop_hash: BlockHash::all_zeros(),
-                        from: self.peer_id,
+                        to: self.peer_id,
                     }))
                 }
             }
@@ -861,7 +899,8 @@
 
                 if self
                     .download_manager
-                    .update_and_check_queue_status(self.client.best_number())
+                    .evaluate_queue_status(self.client.best_number())
+                    .is_overloaded()
                 {
                     SyncAction::None
                 } else {
@@ -882,7 +921,7 @@
             .target_block_number
             .min(latest_block + MAX_GET_BLOCKS_RESPONSE);
 
-        self.download_state = DownloadState::DownloadingNew(latest_block + 1..end + 1);
+        self.state = State::DownloadingNew(latest_block + 1..end + 1);
 
         tracing::debug!(
             latest_block,
@@ -893,7 +932,7 @@
         SyncRequest::Blocks(LocatorRequest {
             locator_hashes,
             stop_hash: BlockHash::all_zeros(),
-            from: self.peer_id,
+            to: self.peer_id,
         })
     }
 
@@ -936,6 +975,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::peer_store::NoPeerStore;
     use subcoin_test_service::block_data;
 
     #[test]
@@ -950,7 +990,7 @@
 
         let peer_id: PeerId = "0.0.0.0:0".parse().unwrap();
         let (mut downloader, _initial_request) =
-            BlocksFirstDownloader::new(client, peer_id, 800000);
+            BlocksFirstDownloader::new(client, peer_id, 800000, Arc::new(NoPeerStore));
 
         let block = block_data()[3].clone();
         let block_hash = block.block_hash();
diff --git a/src/subcoin_network/block_downloader/headers_first.rs.html b/src/subcoin_network/block_downloader/headers_first.rs.html
index 546ea047..2b5c1601 100644
--- a/src/subcoin_network/block_downloader/headers_first.rs.html
+++ b/src/subcoin_network/block_downloader/headers_first.rs.html
@@ -628,7 +628,74 @@
 628
 629
 630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
 
use crate::block_downloader::BlockDownloadManager;
+use crate::peer_store::PeerStore;
 use crate::sync::{LocatorRequest, SyncAction, SyncRequest};
 use crate::{Error, PeerId, SyncStatus};
 use bitcoin::blockdata::block::Header as BitcoinHeader;
@@ -657,7 +724,7 @@
 /// this does not guarantee the block responses from peers are ordered, but it's helpful
 /// for the peers with good connections (i.e., when syncing from a local node).
 #[derive(Debug, Clone)]
-enum BlockDownloadRange {
+enum BlockDownload {
     /// Request all blocks within the specified range in a single `getdata` message.
     ///
     /// This option is only used when the sync node is a local node.
@@ -679,12 +746,18 @@
     },
 }
 
-#[derive(Debug, Clone)]
-enum DownloadState {
+/// Represents the current state of the download process.
+#[derive(Debug, Clone)]
+enum State {
     /// Downloading not started yet.
     Idle,
-    /// Restarting the download process.
-    Restarting,
+    /// Restarting the download by requesting headers.
+    RestartingHeaders,
+    /// Restarting the download by continuing with block download from the specified range.
+    RestartingBlocks {
+        start: IndexedBlock,
+        end: IndexedBlock,
+    },
     /// Peer misbehavior detected, will disconnect the peer shortly.
     Disconnecting,
     /// Actively downloading new headers in the specified range (start, end].
@@ -695,18 +768,21 @@
         start: IndexedBlock,
         end: IndexedBlock,
     },
-    /// Headers downloaded, Actively downloading the corresponding block data (start, end].
-    DownloadingBlocks(BlockDownloadRange),
+    /// Actively downloading blocks corresponding to previously downloaded headers (start, end].
+    DownloadingBlocks(BlockDownload),
     /// All blocks up to the target block have been successfully
     /// downloaded, the download process has been completed.
     Completed,
 }
 
-impl Display for DownloadState {
+impl Display for State {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Self::Idle => write!(f, "Idle"),
-            Self::Restarting => write!(f, "Restarting"),
+            Self::RestartingHeaders => write!(f, "RestartingHeaders"),
+            Self::RestartingBlocks { start, end } => {
+                write!(f, "RestartingBlocks {{ start: {start}, end: {end} }}")
+            }
             Self::Disconnecting => write!(f, "Disconnecting"),
             Self::DownloadingHeaders { start, end } => {
                 write!(f, "DownloadingHeaders {{ start: {start}, end: {end} }}")
@@ -722,21 +798,31 @@
         0..=99_999 => 1024,
         100_000..=199_999 => 512,
         200_000..=299_999 => 128,
-        300_000..=399_999 => 64,
-        400_000..=499_999 => 32,
-        _ => 16,
+        300_000..=399_999 => 32,
+        400_000..=499_999 => 16,
+        _ => 8,
     }
 }
 
-/// Headers-First download strategy.
+/// Headers downloaded up to the next checkpoint.
+struct DownloadedHeaders {
+    /// Ordered map of headers, where the key is the block hash and the value is the block number.
+    ///
+    /// Keep the headers ordered so that fetching the blocks orderly later is possible.
+    headers: IndexMap<BlockHash, u32>,
+    /// Optional range of blocks indicating the completed header download up to the next checkpoint (start, end].
+    completed_range: Option<(IndexedBlock, IndexedBlock)>,
+}
+
+/// Implements the Headers-First download strategy.
 pub struct HeadersFirstDownloader<Block, Client> {
     client: Arc<Client>,
     header_verifier: HeaderVerifier<Block, Client>,
     peer_id: PeerId,
-    download_state: DownloadState,
+    state: State,
     download_manager: BlockDownloadManager,
-    // Keep the headers ordered so that fetching the blocks orderly later is possible.
-    downloaded_headers: IndexMap<BlockHash, u32>,
+    downloaded_headers: DownloadedHeaders,
+    downloaded_blocks_count: usize,
     last_locator_start: u32,
     // TODO: Now it's solely used for the purpose of displaying the sync state.
     // refactor it later.
@@ -754,24 +840,29 @@
         header_verifier: HeaderVerifier<Block, Client>,
         peer_id: PeerId,
         target_block_number: u32,
+        peer_store: Arc<dyn PeerStore>,
     ) -> (Self, SyncAction) {
         let mut headers_first_sync = Self {
             client,
             header_verifier,
             peer_id,
-            download_state: DownloadState::Idle,
-            downloaded_headers: IndexMap::new(),
-            download_manager: BlockDownloadManager::new(),
+            state: State::Idle,
+            downloaded_headers: DownloadedHeaders {
+                headers: IndexMap::new(),
+                completed_range: None,
+            },
+            download_manager: BlockDownloadManager::new(peer_store),
+            downloaded_blocks_count: 0,
             last_locator_start: 0u32,
             target_block_number,
             _phantom: Default::default(),
         };
-        let sync_action = headers_first_sync.prepare_headers_request_action();
+        let sync_action = headers_first_sync.headers_request_action();
         (headers_first_sync, sync_action)
     }
 
     pub(crate) fn sync_status(&self) -> SyncStatus {
-        if self.download_manager.import_queue_is_overloaded {
+        if self.download_manager.queue_status.is_overloaded() {
             SyncStatus::Importing {
                 target: self.target_block_number,
                 peers: vec![self.peer_id],
@@ -784,30 +875,44 @@
         }
     }
 
-    pub(crate) fn sync_peer(&self) -> PeerId {
-        self.peer_id
+    pub(crate) fn replaceable_sync_peer(&self) -> Option<PeerId> {
+        if self.downloaded_blocks_count > 0 {
+            None
+        } else {
+            Some(self.peer_id)
+        }
     }
 
-    pub(crate) fn update_sync_peer(&mut self, peer_id: PeerId, target_block_number: u32) {
+    pub(crate) fn replace_sync_peer(&mut self, peer_id: PeerId, target_block_number: u32) {
         self.peer_id = peer_id;
+        self.downloaded_blocks_count = 0;
         self.target_block_number = target_block_number;
     }
 
+    pub(crate) fn download_manager(&mut self) -> &mut BlockDownloadManager {
+        &mut self.download_manager
+    }
+
     pub(crate) fn on_tick(&mut self) -> SyncAction {
-        if matches!(self.download_state, DownloadState::Restarting) {
-            return self.prepare_headers_request_action();
+        if matches!(self.state, State::RestartingHeaders) {
+            return self.headers_request_action();
+        }
+
+        if let State::RestartingBlocks { start, end } = self.state {
+            return self.start_block_download(start, end);
         }
 
-        if self.download_manager.import_queue_is_overloaded {
-            let import_queue_still_busy = self
+        if self.download_manager.queue_status.is_overloaded() {
+            let still_overloaded = self
                 .download_manager
-                .update_and_check_queue_status(self.client.best_number());
-            if import_queue_still_busy {
+                .evaluate_queue_status(self.client.best_number())
+                .is_overloaded();
+            if still_overloaded {
                 return SyncAction::None;
             } else {
                 // Resume blocks or headers request.
-                match &mut self.download_state {
-                    DownloadState::DownloadingBlocks(BlockDownloadRange::Batches {
+                match &mut self.state {
+                    State::DownloadingBlocks(BlockDownload::Batches {
                         downloaded_batch,
                         waiting,
                         paused,
@@ -828,17 +933,17 @@
                                 .clone_from(&next_batch);
                             return self.blocks_request_action(next_batch);
                         } else {
-                            return self.prepare_headers_request_action();
+                            return self.headers_request_action();
                         }
                     }
                     _ => {
-                        return self.prepare_headers_request_action();
+                        return self.headers_request_action();
                     }
                 }
             }
         }
 
-        if self.download_manager.is_stalled() {
+        if self.download_manager.is_stalled(self.peer_id) {
             return SyncAction::RestartSyncWithStalledPeer(self.peer_id);
         }
 
@@ -847,14 +952,19 @@
 
     pub(crate) fn restart(&mut self, new_peer: PeerId, peer_best: u32) {
         self.peer_id = new_peer;
-        self.downloaded_headers.clear();
         self.download_manager.reset();
+        self.downloaded_blocks_count = 0;
         self.last_locator_start = 0u32;
         self.target_block_number = peer_best;
-        self.download_state = DownloadState::Restarting;
+        if let Some((start, end)) = self.downloaded_headers.completed_range {
+            self.state = State::RestartingBlocks { start, end };
+        } else {
+            self.downloaded_headers.headers.clear();
+            self.state = State::RestartingHeaders;
+        }
     }
 
-    fn prepare_headers_request_action(&mut self) -> SyncAction {
+    fn headers_request_action(&mut self) -> SyncAction {
         let our_best = self.client.best_number();
 
         let Some(checkpoint) = crate::checkpoint::next_checkpoint(our_best + 1) else {
@@ -889,19 +999,19 @@
             .block_locator(Some(our_best), |_height: u32| None)
             .locator_hashes;
 
-        self.download_state = DownloadState::DownloadingHeaders { start, end };
+        self.state = State::DownloadingHeaders { start, end };
+        self.downloaded_headers = DownloadedHeaders {
+            headers: IndexMap::with_capacity((end.number - start.number) as usize),
+            completed_range: None,
+        };
 
         SyncAction::Request(SyncRequest::Headers(LocatorRequest {
             locator_hashes,
             stop_hash: checkpoint.hash,
-            from: self.peer_id,
+            to: self.peer_id,
         }))
     }
 
-    pub(crate) fn download_manager(&mut self) -> &mut BlockDownloadManager {
-        &mut self.download_manager
-    }
-
     // Handle `headers` message.
     //
     // `headers` are expected to contain at most 2000 entries, in ascending order. [b1, b2, b3, ..., b2000].
@@ -916,8 +1026,8 @@
             return SyncAction::None;
         };
 
-        let (start, end) = match &self.download_state {
-            DownloadState::DownloadingHeaders { start, end } => (*start, *end),
+        let (start, end) = match &self.state {
+            State::DownloadingHeaders { start, end } => (*start, *end),
             state => {
                 tracing::debug!(
                     %state,
@@ -931,7 +1041,8 @@
 
         let mut prev_number = if prev_hash == start.hash {
             start.number
-        } else if let Some(block_number) = self.downloaded_headers.get(&prev_hash).copied() {
+        } else if let Some(block_number) = self.downloaded_headers.headers.get(&prev_hash).copied()
+        {
             block_number
         } else if let Some(block_number) = self.client.block_number(prev_hash) {
             block_number
@@ -941,18 +1052,18 @@
                 best_number = ?self.client.info().best_number,
                 "Cannot find the parent of the first header in headers, disconnecting"
             );
-            self.download_state = DownloadState::Disconnecting;
+            self.state = State::Disconnecting;
             return SyncAction::Disconnect(self.peer_id, Error::ParentOfFirstHeaderEntryNotFound);
         };
 
         for header in headers {
             if header.prev_blockhash != prev_hash {
-                self.download_state = DownloadState::Disconnecting;
+                self.state = State::Disconnecting;
                 return SyncAction::Disconnect(self.peer_id, Error::HeadersNotInAscendingOrder);
             }
 
             if !self.header_verifier.has_valid_proof_of_work(&header) {
-                self.download_state = DownloadState::Disconnecting;
+                self.state = State::Disconnecting;
                 return SyncAction::Disconnect(from, Error::BadProofOfWork(header.block_hash()));
             }
 
@@ -961,7 +1072,9 @@
 
             // We can't import the header directly at this moment since creating a Substrate
             // header requires the full block data.
-            self.downloaded_headers.insert(block_hash, block_number);
+            self.downloaded_headers
+                .headers
+                .insert(block_hash, block_number);
 
             prev_hash = block_hash;
             prev_number = block_number;
@@ -972,6 +1085,9 @@
         let target_block_hash = end.hash;
 
         if final_block_number == target_block_number {
+            self.downloaded_headers
+                .completed_range
+                .replace((start, end));
             self.start_block_download(start, end)
         } else {
             tracing::debug!("📄 Downloaded headers ({final_block_number}/{target_block_number})");
@@ -979,7 +1095,7 @@
             SyncAction::Request(SyncRequest::Headers(LocatorRequest {
                 locator_hashes: vec![prev_hash],
                 stop_hash: target_block_hash,
-                from: self.peer_id,
+                to: self.peer_id,
             }))
         }
     }
@@ -990,19 +1106,24 @@
 
         let best_number = self.client.best_number();
 
+        let mut missing_blocks_count = 0usize;
+
         let missing_blocks =
             self.downloaded_headers
+                .headers
                 .iter()
                 .filter_map(|(block_hash, block_number)| {
                     let block_hash = *block_hash;
 
                     if *block_number > best_number {
+                        missing_blocks_count += 1;
                         return Some(block_hash);
                     }
 
                     if self.client.block_exists(block_hash) {
                         None
                     } else {
+                        missing_blocks_count += 1;
                         Some(block_hash)
                     }
                 });
@@ -1018,12 +1139,12 @@
                 best_number,
                 best_queued_number = self.download_manager.best_queued_number,
                 requested_blocks_count = get_data_msg.len(),
-                downloaded_headers = self.downloaded_headers.len(),
+                missing_blocks_count,
+                downloaded_headers_count = self.downloaded_headers.headers.len(),
                 "Downloaded headers from {start} to {end}, requesting blocks",
             );
 
-            self.download_state =
-                DownloadState::DownloadingBlocks(BlockDownloadRange::AllBlocks { start, end });
+            self.state = State::DownloadingBlocks(BlockDownload::AllBlocks { start, end });
 
             get_data_msg
         } else {
@@ -1044,8 +1165,10 @@
                 return SyncAction::None;
             };
 
-            let get_data_msg =
-                prepare_ordered_block_data_request(initial_batch.clone(), &self.downloaded_headers);
+            let get_data_msg = prepare_ordered_block_data_request(
+                initial_batch.clone(),
+                &self.downloaded_headers.headers,
+            );
 
             let old_requested =
                 std::mem::replace(&mut self.download_manager.requested_blocks, initial_batch);
@@ -1058,12 +1181,13 @@
             tracing::debug!(
                 best_number,
                 best_queued_number = self.download_manager.best_queued_number,
-                downloaded_headers = self.downloaded_headers.len(),
+                missing_blocks_count,
+                downloaded_headers_count = self.downloaded_headers.headers.len(),
                 "Headers downloaded, requesting {} blocks in batches (1/{total_batches})",
                 get_data_msg.len(),
             );
 
-            self.download_state = DownloadState::DownloadingBlocks(BlockDownloadRange::Batches {
+            self.state = State::DownloadingBlocks(BlockDownload::Batches {
                 downloaded_batch: 0,
                 waiting: batches,
                 paused: false,
@@ -1078,8 +1202,8 @@
     pub(crate) fn on_block(&mut self, block: BitcoinBlock, from: PeerId) -> SyncAction {
         let block_hash = block.block_hash();
 
-        let block_download_range = match &mut self.download_state {
-            DownloadState::DownloadingBlocks(download_range) => download_range,
+        let block_download = match &mut self.state {
+            State::DownloadingBlocks(block_download) => block_download,
             state => {
                 // TODO: we may receive the blocks from a peer that has been considered as stalled,
                 // should we try to cache and use such blocks since the bandwidth has been consumed
@@ -1109,10 +1233,12 @@
             tracing::trace!("Add pending block #{block_number},{block_hash}");
 
             self.download_manager
-                .add_block(block_number, block_hash, block);
+                .add_block(block_number, block_hash, block, from);
 
-            let should_request_more_headers = match block_download_range {
-                BlockDownloadRange::AllBlocks { start, end } => {
+            self.downloaded_blocks_count += 1;
+
+            let should_request_more_headers = match block_download {
+                BlockDownload::AllBlocks { start, end } => {
                     if end.hash == block_hash {
                         tracing::debug!("Downloaded blocks in ({start}, {end}]");
                         true
@@ -1120,7 +1246,7 @@
                         false
                     }
                 }
-                BlockDownloadRange::Batches {
+                BlockDownload::Batches {
                     downloaded_batch,
                     waiting,
                     paused,
@@ -1128,9 +1254,12 @@
                     if self.download_manager.requested_blocks.is_empty() {
                         *downloaded_batch += 1;
 
+                        let best_number = self.client.best_number();
+
                         if self
                             .download_manager
-                            .update_and_check_queue_status(self.client.best_number())
+                            .evaluate_queue_status(best_number)
+                            .is_overloaded()
                         {
                             *paused = true;
                             return SyncAction::None;
@@ -1138,7 +1267,7 @@
 
                         if let Some(next_batch) = waiting.pop_front() {
                             tracing::debug!(
-                                best_number = self.client.best_number(),
+                                best_number,
                                 best_queued_number = self.download_manager.best_queued_number,
                                 "📦 Downloaded {} blocks in batches ({}/{})",
                                 next_batch.len(),
@@ -1177,8 +1306,10 @@
     }
 
     fn blocks_request_action(&self, blocks_to_download: HashSet<BlockHash>) -> SyncAction {
-        let get_data_msg =
-            prepare_ordered_block_data_request(blocks_to_download, &self.downloaded_headers);
+        let get_data_msg = prepare_ordered_block_data_request(
+            blocks_to_download,
+            &self.downloaded_headers.headers,
+        );
         SyncAction::Request(SyncRequest::Data(get_data_msg, self.peer_id))
     }
 
@@ -1193,14 +1324,15 @@
 
         if self
             .download_manager
-            .update_and_check_queue_status(best_number)
+            .evaluate_queue_status(best_number)
+            .is_overloaded()
         {
             return SyncAction::None;
         }
 
         match crate::checkpoint::next_checkpoint(block_number + 1) {
             Some(checkpoint) => {
-                self.download_state = DownloadState::DownloadingHeaders {
+                self.state = State::DownloadingHeaders {
                     start: IndexedBlock {
                         number: block_number,
                         hash: block_hash,
@@ -1216,14 +1348,14 @@
                 SyncAction::Request(SyncRequest::Headers(LocatorRequest {
                     locator_hashes: vec![block_hash],
                     stop_hash: checkpoint.hash,
-                    from: self.peer_id,
+                    to: self.peer_id,
                 }))
             }
             None => {
                 // We have synced to the last checkpoint, now switch to the Blocks-First
                 // sync to download the remaining blocks.
                 tracing::debug!("No more checkpoint, switching to blocks-first sync");
-                self.download_state = DownloadState::Completed;
+                self.state = State::Completed;
                 SyncAction::SwitchToBlocksFirstSync
             }
         }
diff --git a/src/subcoin_network/connection.rs.html b/src/subcoin_network/connection.rs.html
index 0e4f8170..beb12c3b 100644
--- a/src/subcoin_network/connection.rs.html
+++ b/src/subcoin_network/connection.rs.html
@@ -424,13 +424,8 @@
 424
 425
 426
-427
-428
-429
-430
-431
 
use crate::worker::Event;
-use crate::{Bandwidth, Error, Latency, PeerId};
+use crate::{Bandwidth, Error, PeerId};
 use bitcoin::consensus::{encode, Decodable, Encodable};
 use bitcoin::p2p::message::{NetworkMessage, RawNetworkMessage, MAX_MSG_SIZE};
 use futures::FutureExt;
@@ -487,10 +482,6 @@
     /// Indicates whether the connection was initiated by the
     /// local node (`Outbound`) or by the remote peer (`Inbound`).
     pub direction: Direction,
-    /// Time took to make the connection.
-    ///
-    /// Only make sense for the outbound connection.
-    pub connect_latency: Latency,
     /// Channel for sending messages to the peer over this connection.
     ///
     /// This `ConnectionWriter` enables the local node to transmit data
@@ -649,7 +640,6 @@
                 peer_addr,
                 local_addr,
                 direction,
-                connect_latency,
                 writer: network_message_sender,
                 disconnect_signal: disconnect_signal.clone(),
             }))
diff --git a/src/subcoin_network/lib.rs.html b/src/subcoin_network/lib.rs.html
index ade6500b..27eeb7c9 100644
--- a/src/subcoin_network/lib.rs.html
+++ b/src/subcoin_network/lib.rs.html
@@ -468,6 +468,8 @@
 468
 469
 470
+471
+472
 
//! # Bitcoin Network
 //!
 //! This crate facilitates communication with other nodes in the Bitcoin P2P network. It handles
@@ -514,7 +516,7 @@
 use crate::connection::ConnectionInitiator;
 use crate::metrics::BandwidthMetrics;
 use crate::network::NetworkWorkerMessage;
-use crate::peer_store::PeerStore;
+use crate::peer_store::{PersistentPeerStore, PersistentPeerStoreHandle};
 use crate::worker::NetworkWorker;
 use bitcoin::p2p::ServiceFlags;
 use bitcoin::{BlockHash, Network as BitcoinNetwork};
@@ -535,7 +537,7 @@
 use tokio::sync::oneshot;
 
 pub use crate::network::{NetworkHandle, NetworkStatus, SendTransactionResult, SyncStatus};
-pub use crate::sync::{PeerLatency, PeerSync, PeerSyncState};
+pub use crate::sync::{PeerSync, PeerSyncState};
 
 /// Identifies a peer.
 pub type PeerId = SocketAddr;
@@ -584,8 +586,10 @@
     TooManyInventoryItems,
     #[error("Ping timeout")]
     PingTimeout,
-    #[error("Ping latency exceeds the threshold")]
-    PingLatencyTooHigh,
+    #[error("Ping latency ({0}) exceeds the threshold")]
+    PingLatencyTooHigh(Latency),
+    #[error("Peer is deprioritized for syncing and has encountered multiple failures")]
+    UnreliablePeer,
     #[error("Peer's latency ({0} ms) is too high")]
     SlowPeer(Latency),
     #[error("Unexpected pong message")]
@@ -828,13 +832,13 @@
             tracing::info!("Subcoin block sync is disabled until Substrate fast sync is complete");
         }
 
-        let peer_store = PeerStore::new(
-            &config.base_path,
-            config.max_outbound_peers,
-            config.persistent_peer_latency_threshold,
-        );
+        let (sender, receiver) = tracing_unbounded("mpsc_subcoin_peer_store", 10_000);
+        let (persistent_peer_store, persistent_peers) =
+            PersistentPeerStore::new(&config.base_path, config.max_outbound_peers);
+        let persistent_peer_store_handle =
+            PersistentPeerStoreHandle::new(config.persistent_peer_latency_threshold, sender);
 
-        let persistent_peers = peer_store.peer_set();
+        spawn_handle.spawn("peer-store", None, persistent_peer_store.run(receiver));
 
         let network_worker = NetworkWorker::new(
             worker::Params {
@@ -850,7 +854,7 @@
                 connection_initiator: connection_initiator.clone(),
                 max_outbound_peers: config.max_outbound_peers,
                 enable_block_sync: config.enable_block_sync_on_startup,
-                peer_store,
+                peer_store: Arc::new(persistent_peer_store_handle),
             },
             registry.as_ref(),
         );
diff --git a/src/subcoin_network/peer_manager.rs.html b/src/subcoin_network/peer_manager.rs.html
index eb23628f..1c44426c 100644
--- a/src/subcoin_network/peer_manager.rs.html
+++ b/src/subcoin_network/peer_manager.rs.html
@@ -766,6 +766,11 @@
 766
 767
 768
+769
+770
+771
+772
+773
 
use crate::address_book::AddressBook;
 use crate::connection::{ConnectionInitiator, ConnectionWriter, Direction, NewConnection};
 use crate::metrics::Metrics;
@@ -794,11 +799,20 @@
 pub const PROTOCOL_VERSION: u32 = 70016;
 
 /// Minimum supported peer protocol version.
+///
 /// This version includes support for the `sendheaders` feature.
 pub const MIN_PROTOCOL_VERSION: u32 = 70012;
 
-/// Peer is considered as a slow one if the average ping latency is higher than 5 seconds.
-const SLOW_PEER_LATENCY: Latency = 5_000;
+/// The maximum allowable peer latency in milliseconds before disconnection.
+///
+/// If a peer's latency exceeds this threshold (2000ms), it will be disconnected immediately.
+pub const PEER_LATENCY_THRESHOLD: Latency = 2000;
+
+/// The threshold for classifying a peer as "slow", based on average ping latency in milliseconds.
+///
+/// A peer is considered slow if its average latency exceeds 500ms. Slow peers may be evicted from
+/// the network to maintain overall performance.
+const SLOW_PEER_LATENCY: Latency = 500;
 
 /// Interval for evicting the slowest peer, 10 minutes.
 ///
@@ -858,7 +872,7 @@
 pub struct NewPeer {
     pub peer_id: PeerId,
     pub best_number: u32,
-    pub connect_latency: Latency,
+    pub latency: Latency,
 }
 
 /// Handshake state.
@@ -902,22 +916,26 @@
 }
 
 #[derive(Debug, Clone, Default)]
-pub struct PingLatency {
-    pub received_pongs: u64,
-    pub total_latency: Latency,
+pub struct LatencyTracker {
+    /// Number of ping responses received.
+    received_pongs: u64,
+    /// Accumulated total latency in milliseconds.
+    total_latency: Latency,
 }
 
-impl PingLatency {
-    fn on_pong(&mut self, latency: Latency) {
+impl LatencyTracker {
+    /// Updates the ping latency data and returns the latest average latency.
+    fn record_pong(&mut self, latency: Latency) -> Latency {
         self.received_pongs = self.received_pongs.saturating_add(1);
         self.total_latency = self.total_latency.saturating_add(latency);
+        self.total_latency / self.received_pongs as u128
     }
 
-    fn average(&self) -> Latency {
+    fn calc_average(&self) -> Option<Latency> {
         if self.received_pongs == 0 {
-            return u128::MAX;
+            return None;
         }
-        self.total_latency / self.received_pongs as u128
+        Some(self.total_latency / self.received_pongs as u128)
     }
 }
 
@@ -935,8 +953,8 @@
 }
 
 impl PingState {
-    const PING_INTERVAL: Duration = Duration::from_secs(120);
     const PING_TIMEOUT: Duration = Duration::from_secs(30);
+    const PING_INTERVAL: Duration = Duration::from_secs(120);
 
     fn should_ping(&self) -> bool {
         match self {
@@ -951,6 +969,12 @@
             Self::AwaitingPong { last_ping_at, .. } => last_ping_at.elapsed() >= Self::PING_TIMEOUT,
         }
     }
+
+    fn idle() -> Self {
+        Self::Idle {
+            last_pong_at: Instant::now(),
+        }
+    }
 }
 
 /// A peer with protocol information.
@@ -982,7 +1006,7 @@
     /// receive them instead of `addr`.
     pub want_addrv2: bool,
     /// Latency of performed pings.
-    pub ping_latency: PingLatency,
+    pub ping_latency: LatencyTracker,
     /// Current ping state.
     pub ping_state: PingState,
     /// Whether the ping has ever sent to the peer.
@@ -1004,10 +1028,8 @@
             nonce: msg.nonce,
             prefer_headers: false,
             want_addrv2: false,
-            ping_latency: PingLatency::default(),
-            ping_state: PingState::Idle {
-                last_pong_at: Instant::now(),
-            },
+            ping_latency: LatencyTracker::default(),
+            ping_state: PingState::idle(),
             has_sent_ping: false,
             direction,
         }
@@ -1017,7 +1039,7 @@
 #[derive(Debug)]
 pub(crate) struct SlowPeer {
     pub(crate) peer_id: PeerId,
-    pub(crate) peer_latency: Latency,
+    pub(crate) latency: Latency,
 }
 
 /// Manages the peers in the network.
@@ -1027,7 +1049,6 @@
     address_book: AddressBook,
     handshaking_peers: HashMap<PeerId, HandshakeState>,
     connections: HashMap<PeerId, Connection>,
-    connection_latencies: HashMap<PeerId, Latency>,
     connected_peers: HashMap<PeerId, PeerInfo>,
     max_outbound_peers: usize,
     connection_initiator: ConnectionInitiator,
@@ -1057,7 +1078,6 @@
             address_book: AddressBook::new(true, MAX_AVAILABLE_ADDRESSES),
             handshaking_peers: HashMap::new(),
             connections: HashMap::new(),
-            connection_latencies: HashMap::new(),
             connected_peers: HashMap::new(),
             max_outbound_peers,
             connection_initiator,
@@ -1136,18 +1156,18 @@
                 self.connected_peers
                     .iter()
                     .filter_map(|(peer_id, peer_info)| {
-                        let average_latency = peer_info.ping_latency.average();
+                        let avg_latency = peer_info.ping_latency.calc_average()?;
 
-                        if average_latency > SLOW_PEER_LATENCY {
-                            Some((peer_id, average_latency))
+                        if avg_latency > SLOW_PEER_LATENCY {
+                            Some((peer_id, avg_latency))
                         } else {
                             None
                         }
                     })
-                    .max_by_key(|(_peer_id, average_latency)| *average_latency)
-                    .map(|(peer_id, peer_latency)| SlowPeer {
+                    .max_by_key(|(_peer_id, avg_latency)| *avg_latency)
+                    .map(|(peer_id, latency)| SlowPeer {
                         peer_id: *peer_id,
-                        peer_latency,
+                        latency,
                     })
             } else {
                 None
@@ -1216,7 +1236,6 @@
         self.address_book.mark_disconnected(&peer_id);
         self.handshaking_peers.remove(&peer_id);
         self.connected_peers.remove(&peer_id);
-        self.connection_latencies.remove(&peer_id);
     }
 
     /// Sets the prefer addrv2 flag for a peer.
@@ -1233,7 +1252,8 @@
         });
     }
 
-    pub(crate) fn update_last_eviction(&mut self) {
+    pub(crate) fn evict(&mut self, peer_id: PeerId, reason: Error) {
+        self.disconnect(peer_id, reason);
         self.last_eviction = Instant::now();
     }
 
@@ -1260,13 +1280,18 @@
             .count()
     }
 
+    pub(crate) fn peer_best_number(&self, peer_id: PeerId) -> Option<u32> {
+        self.connected_peers
+            .get(&peer_id)
+            .map(|peer_info| peer_info.best_height)
+    }
+
     /// Handles a new connection.
     pub(crate) fn on_new_connection(&mut self, new_connection: NewConnection) {
         let NewConnection {
             peer_addr,
             local_addr,
             direction,
-            connect_latency,
             writer,
             disconnect_signal,
         } = new_connection;
@@ -1325,7 +1350,6 @@
         }
 
         self.connections.insert(peer_addr, connection);
-        self.connection_latencies.insert(peer_addr, connect_latency);
         self.handshaking_peers.insert(peer_addr, handshake_state);
     }
 
@@ -1421,11 +1445,7 @@
     }
 
     /// Handles receiving a verack message.
-    pub(crate) fn on_verack(
-        &mut self,
-        peer_id: PeerId,
-        direction: Direction,
-    ) -> Result<NewPeer, Error> {
+    pub(crate) fn on_verack(&mut self, peer_id: PeerId, direction: Direction) -> Result<(), Error> {
         let Some(handshake_state) = self.handshaking_peers.remove(&peer_id) else {
             return Err(Error::PeerNotFound(peer_id));
         };
@@ -1437,15 +1457,6 @@
 
         let peer_info = PeerInfo::new(version, direction);
 
-        let new_peer = NewPeer {
-            peer_id,
-            best_number: peer_info.best_height,
-            connect_latency: self
-                .connection_latencies
-                .remove(&peer_id)
-                .ok_or(Error::PeerNotFound(peer_id))?,
-        };
-
         self.connected_peers.insert(peer_id, peer_info);
 
         match direction {
@@ -1464,7 +1475,10 @@
             self.send(peer_id, NetworkMessage::GetAddr)?;
         }
 
-        Ok(new_peer)
+        // Immediately ping the peer on ack.
+        self.send_pings(vec![peer_id]);
+
+        Ok(())
     }
 
     pub(crate) fn on_addr(&mut self, peer_id: PeerId, addresses: Vec<(u32, Address)>) {
@@ -1522,16 +1536,12 @@
             }
         };
 
-        peer_info.ping_latency.on_pong(latency);
-        peer_info.ping_state = PingState::Idle {
-            last_pong_at: Instant::now(),
-        };
-
-        let average_latency = peer_info.ping_latency.average();
+        let avg_latency = peer_info.ping_latency.record_pong(latency);
+        peer_info.ping_state = PingState::idle();
 
-        tracing::trace!("Received pong from {peer_id} (Avg. Latency: {average_latency}ms)");
+        tracing::trace!("Received pong from {peer_id} (Avg. Latency: {avg_latency}ms)");
 
-        Ok(average_latency)
+        Ok(avg_latency)
     }
 }
 
\ No newline at end of file diff --git a/src/subcoin_network/peer_store.rs.html b/src/subcoin_network/peer_store.rs.html index 31fbc83f..fb43d078 100644 --- a/src/subcoin_network/peer_store.rs.html +++ b/src/subcoin_network/peer_store.rs.html @@ -221,13 +221,144 @@ 221 222 223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351
//! This module maintains a set of high-quality peers persistently, allowing the node to connect
 //! to good peers without a long discovery process.
 
 use crate::{Latency, PeerId};
+use futures::StreamExt;
+use sc_utils::mpsc::{TracingUnboundedReceiver, TracingUnboundedSender};
 use serde::{Deserialize, Serialize};
 use std::cmp::Ordering;
 use std::collections::HashMap;
+use std::fmt::Debug;
 use std::io::Read;
 use std::path::{Path, PathBuf};
 use std::time::{Instant, SystemTime};
@@ -241,134 +372,240 @@
 const SAVE_INTERVAL: u64 = 60 * 5;
 
 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
-struct GoodPeer {
-    latency: Latency,
-    last_seen: SystemTime,
+struct PeerStats {
+    /// The current latency to the peer, in milliseconds.
+    latency: Latency,
+    /// Timestamp when the peer was last seen.
+    last_seen: SystemTime,
+    /// Number of blocks successfully downloaded from the peer.
+    downloaded_blocks_count: usize,
+    /// The number of failed interactions (e.g., disconnections, timeouts).
+    failure_count: usize,
 }
 
-impl GoodPeer {
-    /// Returns true if `self` is a better peer than `other`.
+impl PeerStats {
+    /// Compares `self` with `other` to determine which peer is better.
+    ///
+    /// A peer is considered better based on the following criteria (in order):
+    /// 1. Fewer failures (disconnections, timeouts).
+    /// 2. More blocks successfully downloaded.
+    /// 3. Lower latency (better response time).
+    /// 4. More recent interaction (newer `last_seen` timestamp).
     fn is_better_than(&self, other: &Self) -> bool {
-        // First, compare latency (lower latency is better)
-        if self.latency < other.latency {
-            return true;
+        // 1. Prioritize peers with fewer failures.
+        if self.failure_count != other.failure_count {
+            return self.failure_count < other.failure_count;
         }
 
-        if self.latency > other.latency {
-            return false;
+        // 2. Next, prioritize peers with more blocks downloaded.
+        if self.downloaded_blocks_count != other.downloaded_blocks_count {
+            return self.downloaded_blocks_count > other.downloaded_blocks_count;
         }
 
-        // If latencies are the same, compare last_seen (newer is better)
+        // 3. Then, prioritize peers with lower latency.
+        if self.latency != other.latency {
+            return self.latency < other.latency;
+        }
+
+        // 4. Finally, if all else is equal, prefer peers that were seen more recently.
         self.last_seen > other.last_seen
     }
 }
 
+pub trait PeerStore: Send + Sync {
+    /// Adds or updates a peer in the store if its latency is below the configured threshold.
+    fn try_add_peer(&self, peer_id: PeerId, latency: Latency);
+
+    /// Removes a peer from the store.
+    fn remove_peer(&self, peer_id: PeerId);
+
+    /// Logs the successful download of a block from a peer.
+    fn record_block_download(&self, peer_id: PeerId);
+
+    /// Logs a failure interaction with a peer.
+    fn record_failure(&self, peer_id: PeerId);
+}
+
+pub struct NoPeerStore;
+
+impl PeerStore for NoPeerStore {
+    fn try_add_peer(&self, _peer_id: PeerId, _latency: Latency) {}
+    fn remove_peer(&self, _peer_id: PeerId) {}
+    fn record_block_download(&self, _peer_id: PeerId) {}
+    fn record_failure(&self, _peer_id: PeerId) {}
+}
+
+#[derive(Debug)]
+pub(crate) enum PeerStoreMessage {
+    StorePeer(PeerId, Latency, SystemTime),
+    RemovePeer(PeerId),
+    RecordBlockDownload(PeerId),
+    RecordFailure(PeerId),
+}
+
+#[derive(Clone, Debug)]
+pub(crate) struct PersistentPeerStoreHandle {
+    persistent_peer_latency_threshold: u128,
+    sender: TracingUnboundedSender<PeerStoreMessage>,
+}
+
+impl PersistentPeerStoreHandle {
+    pub(crate) fn new(
+        persistent_peer_latency_threshold: u128,
+        sender: TracingUnboundedSender<PeerStoreMessage>,
+    ) -> Self {
+        Self {
+            persistent_peer_latency_threshold,
+            sender,
+        }
+    }
+}
+
+impl PeerStore for PersistentPeerStoreHandle {
+    fn try_add_peer(&self, peer_id: PeerId, latency: Latency) {
+        if latency < self.persistent_peer_latency_threshold {
+            let _ = self.sender.unbounded_send(PeerStoreMessage::StorePeer(
+                peer_id,
+                latency,
+                SystemTime::now(),
+            ));
+        }
+    }
+
+    fn remove_peer(&self, peer_id: PeerId) {
+        let _ = self
+            .sender
+            .unbounded_send(PeerStoreMessage::RemovePeer(peer_id));
+    }
+
+    fn record_block_download(&self, peer_id: PeerId) {
+        let _ = self
+            .sender
+            .unbounded_send(PeerStoreMessage::RecordBlockDownload(peer_id));
+    }
+
+    fn record_failure(&self, peer_id: PeerId) {
+        let _ = self
+            .sender
+            .unbounded_send(PeerStoreMessage::RecordFailure(peer_id));
+    }
+}
+
 /// Manages a set of high-quality peers and periodically persists them to disk.
 #[derive(Debug)]
-pub struct PeerStore {
-    peers: HashMap<PeerId, GoodPeer>,
+pub(crate) struct PersistentPeerStore {
+    peers: HashMap<PeerId, PeerStats>,
     sorted_peers: Vec<PeerId>,
     peers_changed: bool,
     capacity: usize,
-    good_peer_latency_threshold: u128,
     file_path: PathBuf,
     last_saved_at: Instant,
 }
 
-impl PeerStore {
-    pub fn new(base_path: &Path, capacity: usize, good_peer_latency_threshold: u128) -> Self {
+impl PersistentPeerStore {
+    pub(crate) fn new(base_path: &Path, capacity: usize) -> (Self, Vec<PeerId>) {
         let file_path = base_path.join(PEER_STORE_FILE_NAME);
 
         let peers = load_peers(&file_path)
             .map_err(|err| {
-                tracing::error!(
-                    ?err,
-                    "Error occurred when loading peers from {}",
-                    file_path.display()
-                );
+                tracing::error!(?err, "Failed to load peers from {}", file_path.display());
             })
             .unwrap_or_default();
 
-        let sorted_peers = peers.keys().cloned().collect();
+        let persistent_peers = peers.keys().cloned().collect::<Vec<_>>();
 
-        Self {
+        let peer_store = Self {
             peers,
-            sorted_peers,
-            capacity: if capacity > MAX_CAPACITY {
-                MAX_CAPACITY
-            } else {
-                capacity
-            },
+            sorted_peers: persistent_peers.clone(),
+            capacity: capacity.min(MAX_CAPACITY),
             file_path,
             peers_changed: false,
-            good_peer_latency_threshold,
             last_saved_at: Instant::now(),
-        }
-    }
+        };
 
-    pub fn peer_set(&self) -> Vec<PeerId> {
-        self.peers.keys().cloned().collect()
+        (peer_store, persistent_peers)
     }
 
-    /// Adds or updates a peer in the store if its latency is below the configured threshold.
-    pub fn add_peer_if_latency_acceptable(&mut self, peer_id: PeerId, latency: Latency) {
-        if latency < self.good_peer_latency_threshold {
-            self.add_or_update_peer(peer_id, latency, SystemTime::now());
+    pub(crate) async fn run(mut self, mut receiver: TracingUnboundedReceiver<PeerStoreMessage>) {
+        while let Some(msg) = receiver.next().await {
+            match msg {
+                PeerStoreMessage::StorePeer(peer_id, latency, last_seen) => {
+                    self.store_peer(peer_id, latency, last_seen);
+                }
+                PeerStoreMessage::RemovePeer(peer_id) => {
+                    self.remove_peer(peer_id);
+                }
+                PeerStoreMessage::RecordBlockDownload(peer_id) => {
+                    if let Some(peer) = self.peers.get_mut(&peer_id) {
+                        peer.downloaded_blocks_count += 1;
+                        self.peers_changed = true;
+                        self.process_peer_set_changes();
+                    }
+                }
+                PeerStoreMessage::RecordFailure(peer_id) => {
+                    if let Some(peer) = self.peers.get_mut(&peer_id) {
+                        peer.failure_count += 1;
+                        self.peers_changed = true;
+                        self.process_peer_set_changes();
+                    }
+                }
+            }
         }
     }
 
-    fn add_or_update_peer(&mut self, peer_id: PeerId, latency: Latency, last_seen: SystemTime) {
-        let new_peer = GoodPeer { latency, last_seen };
-
+    fn store_peer(&mut self, peer_id: PeerId, latency: Latency, last_seen: SystemTime) {
         if let Some(peer) = self.peers.get_mut(&peer_id) {
             peer.latency = latency;
             peer.last_seen = last_seen;
-            self.peers_changed = true;
-            self.process_peer_changes();
-            return;
-        }
-
-        // Check if we need to replace the lowest quality peer.
-        if self.peers.len() >= self.capacity {
-            if let Some(lowest_peer_id) = self.sorted_peers.first() {
-                let Some(lowest_peer) = self.peers.get(lowest_peer_id) else {
-                    return;
-                };
-
-                if !new_peer.is_better_than(lowest_peer) {
-                    // New peer is not better, no need to add.
-                    return;
+        } else {
+            let new_peer = PeerStats {
+                latency,
+                last_seen,
+                downloaded_blocks_count: 0,
+                failure_count: 0,
+            };
+
+            // Check if we need to replace the lowest quality peer.
+            if self.peers.len() >= self.capacity {
+                if let Some(lowest_peer_id) = self.sorted_peers.first() {
+                    let Some(lowest_peer) = self.peers.get(lowest_peer_id) else {
+                        return;
+                    };
+
+                    if !new_peer.is_better_than(lowest_peer) {
+                        // New peer is not better, no need to add.
+                        return;
+                    }
+
+                    // Remove the worst peer if it's going to be replaced.
+                    self.peers.remove(lowest_peer_id);
+                    self.sorted_peers.remove(0);
                 }
-
-                // Remove the worst peer if it's going to be replaced.
-                self.peers.remove(lowest_peer_id);
-                self.sorted_peers.remove(0);
             }
+
+            self.peers.insert(peer_id, new_peer);
         }
 
-        self.peers.insert(peer_id, new_peer);
         self.peers_changed = true;
-
-        self.process_peer_changes();
+        self.process_peer_set_changes();
     }
 
-    /// Removes a peer from the store.
-    pub fn remove_peer(&mut self, peer_id: PeerId) {
+    fn remove_peer(&mut self, peer_id: PeerId) {
         if self.peers.remove(&peer_id).is_some() {
             self.peers_changed = true;
-            self.process_peer_changes();
+            self.process_peer_set_changes();
         }
     }
 
     /// Update the sorted peers and write peers to disk if needed.
-    fn process_peer_changes(&mut self) {
+    fn process_peer_set_changes(&mut self) {
         self.update_sorted_peers();
 
         // Save to disk only if peers have changed and enough time has passed since the last save.
         if self.peers_changed && self.last_saved_at.elapsed().as_secs() > SAVE_INTERVAL {
             match self.save_peers() {
                 Ok(()) => {
-                    self.last_saved_at = std::time::Instant::now();
+                    self.last_saved_at = Instant::now();
                     self.peers_changed = false;
                 }
                 Err(err) => {
@@ -402,7 +639,7 @@
     }
 }
 
-fn load_peers(file_path: &Path) -> std::io::Result<HashMap<PeerId, GoodPeer>> {
+fn load_peers(file_path: &Path) -> std::io::Result<HashMap<PeerId, PeerStats>> {
     match std::fs::File::open(file_path) {
         Ok(mut file) => {
             let mut data = String::new();
@@ -428,20 +665,39 @@
 
     #[test]
     fn test_peer_store() {
-        let mut peer_store = PeerStore::new(&PathBuf::from("/"), 10, 200);
+        let (mut peer_store, _) = PersistentPeerStore::new(&PathBuf::from("/"), 10);
 
         let now = SystemTime::now();
         let peer1: PeerId = "127.0.0.1:8001".parse().unwrap();
         let peer2: PeerId = "127.0.0.1:8002".parse().unwrap();
         let peer3: PeerId = "127.0.0.1:8003".parse().unwrap();
         let peer4: PeerId = "127.0.0.1:8004".parse().unwrap();
-        peer_store.add_or_update_peer(peer1, 10, now);
-        peer_store.add_or_update_peer(peer2, 10, now.checked_sub(Duration::from_secs(1)).unwrap());
-        peer_store.add_or_update_peer(peer3, 10, now.checked_add(Duration::from_secs(1)).unwrap());
-        peer_store.add_or_update_peer(peer4, 5, now.checked_sub(Duration::from_secs(1)).unwrap());
+        peer_store.store_peer(peer1, 10, now);
+        peer_store.store_peer(peer2, 10, now.checked_sub(Duration::from_secs(1)).unwrap());
+        peer_store.store_peer(peer3, 10, now.checked_add(Duration::from_secs(1)).unwrap());
+        peer_store.store_peer(peer4, 5, now.checked_sub(Duration::from_secs(1)).unwrap());
+
+        peer_store
+            .peers
+            .get_mut(&peer1)
+            .unwrap()
+            .downloaded_blocks_count = 1000;
+        peer_store
+            .peers
+            .get_mut(&peer2)
+            .unwrap()
+            .downloaded_blocks_count = 100;
+        peer_store.peers.get_mut(&peer3).unwrap().failure_count = 10;
+        peer_store
+            .peers
+            .get_mut(&peer3)
+            .unwrap()
+            .downloaded_blocks_count = 1;
+
+        peer_store.update_sorted_peers();
 
         assert_eq!(peer_store.peers.len(), 4);
-        assert_eq!(peer_store.sorted_peers, vec![peer4, peer3, peer1, peer2]);
+        assert_eq!(peer_store.sorted_peers, vec![peer1, peer2, peer4, peer3]);
     }
 }
 
\ No newline at end of file diff --git a/src/subcoin_network/sync.rs.html b/src/subcoin_network/sync.rs.html index 626534c9..fcf5466d 100644 --- a/src/subcoin_network/sync.rs.html +++ b/src/subcoin_network/sync.rs.html @@ -683,8 +683,65 @@ 683 684 685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741
use crate::block_downloader::{BlocksFirstDownloader, HeadersFirstDownloader};
 use crate::peer_manager::NewPeer;
+use crate::peer_store::PeerStore;
 use crate::{Error, Latency, PeerId, SyncStatus, SyncStrategy};
 use bitcoin::blockdata::block::Header as BitcoinHeader;
 use bitcoin::p2p::message_blockdata::Inventory;
@@ -696,7 +753,6 @@
 use serde::{Deserialize, Serialize};
 use sp_consensus::BlockOrigin;
 use sp_runtime::traits::Block as BlockT;
-use std::cmp::Ordering as CmpOrdering;
 use std::collections::{HashMap, HashSet};
 use std::marker::PhantomData;
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -706,19 +762,25 @@
 // Do major sync when the current tip falls behind the network by 144 blocks (roughly one day).
 const MAJOR_SYNC_GAP: u32 = 144;
 
-const LATENCY_IMPROVEMENT_THRESHOLD: f64 = 1.2;
+const LATENCY_IMPROVEMENT_THRESHOLD: u128 = 4;
 
 // Define a constant for the low ping latency cutoff, in milliseconds.
 const LOW_LATENCY_CUTOFF: Latency = 20;
 
+/// Maximum number of syncing retries for a deprioritized peer.
+const MAX_STALLS: usize = 5;
+
 /// The state of syncing between a Peer and ourselves.
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
+#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize, Hash)]
 #[serde(rename_all = "camelCase")]
 pub enum PeerSyncState {
     /// Available for sync requests.
     Available,
-    /// The peer has been discouraged due to syncing from this peer was stalled before.
-    Discouraged,
+    /// The peer has been deprioritized due to past syncing issues (e.g., stalling).
+    Deprioritized {
+        /// Number of times the peer has stalled.
+        stalled_count: usize,
+    },
     /// Actively downloading new blocks, starting from the given Number.
     DownloadingNew { start: u32 },
 }
@@ -728,37 +790,20 @@
     pub fn is_available(&self) -> bool {
         matches!(self, Self::Available)
     }
-}
 
-/// Letency of the peer.
-///
-/// The initial connection time is used as the baseline, the ping mechanism is
-/// used for more accurate latency estimate after the connection is established.
-#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub enum PeerLatency {
-    /// Connection latency.
-    ///
-    /// Only make sense for the outbound connection.
-    Connect(Latency),
-    /// Average ping latency.
-    Ping(Latency),
-}
-
-impl Ord for PeerLatency {
-    fn cmp(&self, other: &Self) -> CmpOrdering {
-        match (self, other) {
-            (Self::Connect(a), Self::Connect(b)) => a.cmp(b),
-            (Self::Connect(_), Self::Ping(_)) => CmpOrdering::Less,
-            (Self::Ping(_), Self::Connect(_)) => CmpOrdering::Greater,
-            (Self::Ping(a), Self::Ping(b)) => a.cmp(b),
+    fn stalled_count(&self) -> usize {
+        match self {
+            Self::Deprioritized { stalled_count } => *stalled_count,
+            _ => 0,
         }
     }
-}
 
-impl PartialOrd for PeerLatency {
-    fn partial_cmp(&self, other: &Self) -> Option<CmpOrdering> {
-        Some(self.cmp(other))
+    /// Determines if the peer is permanently deprioritized based on the stall count.
+    fn is_permanently_deprioritized(&self) -> bool {
+        match self {
+            PeerSyncState::Deprioritized { stalled_count } => *stalled_count > MAX_STALLS,
+            _ => false,
+        }
     }
 }
 
@@ -771,7 +816,7 @@
     /// The number of the best block that we've seen for this peer.
     pub best_number: u32,
     /// Latency of connection to this peer.
-    pub latency: PeerLatency,
+    pub latency: Latency,
     /// The state of syncing this peer is in for us, generally categories
     /// into `Available` or "busy" with something as defined by `PeerSyncState`.
     pub state: PeerSyncState,
@@ -782,7 +827,7 @@
 pub(crate) struct LocatorRequest {
     pub locator_hashes: Vec<BlockHash>,
     pub stop_hash: BlockHash,
-    pub from: PeerId,
+    pub to: PeerId,
 }
 
 /// Represents different kinds of sync requests.
@@ -806,7 +851,7 @@
     SwitchToBlocksFirstSync,
     /// Disconnect from the peer for the given reason.
     Disconnect(PeerId, Error),
-    /// Make this peer as discouraged and restart the current syncing
+    /// Make this peer as deprioritized and restart the current syncing
     /// process using other sync candidates if there are any.
     RestartSyncWithStalledPeer(PeerId),
     /// Blocks-First sync finished, switch syncing state to idle.
@@ -819,9 +864,9 @@
 // might be in during the sync process.
 enum Syncing<Block, Client> {
     /// Blocks-First sync.
-    BlocksFirstSync(Box<BlocksFirstDownloader<Block, Client>>),
+    BlocksFirst(Box<BlocksFirstDownloader<Block, Client>>),
     /// Headers-First sync.
-    HeadersFirstSync(Box<HeadersFirstDownloader<Block, Client>>),
+    HeadersFirst(Box<HeadersFirstDownloader<Block, Client>>),
     /// Not syncing.
     ///
     /// This could indicate that the node is either fully synced
@@ -831,7 +876,7 @@
 
 impl<Block, Client> Syncing<Block, Client> {
     fn is_major_syncing(&self) -> bool {
-        matches!(self, Self::BlocksFirstSync(_) | Self::HeadersFirstSync(_))
+        matches!(self, Self::BlocksFirst(_) | Self::HeadersFirst(_))
     }
 }
 
@@ -843,7 +888,8 @@
     header_verifier: HeaderVerifier<Block, Client>,
     /// The active peers that we are using to sync and their PeerSync status
     pub(crate) peers: HashMap<PeerId, PeerSync>,
-    syncing: Syncing<Block, Client>,
+    /// Current syncing state.
+    syncing: Syncing<Block, Client>,
     /// Handle of the import queue.
     import_queue: BlockImportQueue,
     /// Block syncing strategy.
@@ -855,7 +901,9 @@
     /// Randomness generator.
     rng: fastrand::Rng,
     /// Broadcasted blocks that are being requested.
-    broadcasted_blocks: HashSet<BlockHash>,
+    inflight_announced_blocks: HashSet<BlockHash>,
+    /// Handle of peer store.
+    peer_store: Arc<dyn PeerStore>,
     _phantom: PhantomData<Block>,
 }
 
@@ -872,18 +920,20 @@
         sync_strategy: SyncStrategy,
         is_major_syncing: Arc<AtomicBool>,
         enable_block_sync: bool,
+        peer_store: Arc<dyn PeerStore>,
     ) -> Self {
         Self {
             client,
             header_verifier,
             peers: HashMap::new(),
-            import_queue,
             syncing: Syncing::Idle,
+            import_queue,
             sync_strategy,
             is_major_syncing,
             enable_block_sync,
             rng: fastrand::Rng::new(),
-            broadcasted_blocks: HashSet::new(),
+            inflight_announced_blocks: HashSet::new(),
+            peer_store,
             _phantom: Default::default(),
         }
     }
@@ -891,16 +941,16 @@
     pub(super) fn sync_status(&self) -> SyncStatus {
         match &self.syncing {
             Syncing::Idle => SyncStatus::Idle,
-            Syncing::BlocksFirstSync(downloader) => downloader.sync_status(),
-            Syncing::HeadersFirstSync(downloader) => downloader.sync_status(),
+            Syncing::BlocksFirst(downloader) => downloader.sync_status(),
+            Syncing::HeadersFirst(downloader) => downloader.sync_status(),
         }
     }
 
     pub(super) fn on_tick(&mut self) -> SyncAction {
         match &mut self.syncing {
             Syncing::Idle => SyncAction::None,
-            Syncing::BlocksFirstSync(downloader) => downloader.on_tick(),
-            Syncing::HeadersFirstSync(downloader) => downloader.on_tick(),
+            Syncing::BlocksFirst(downloader) => downloader.on_tick(),
+            Syncing::HeadersFirst(downloader) => downloader.on_tick(),
         }
     }
 
@@ -908,6 +958,18 @@
         self.import_queue.block_import_results().await
     }
 
+    pub(super) fn unreliable_peers(&self) -> Vec<PeerId> {
+        self.peers
+            .iter()
+            .filter_map(|(peer_id, peer)| {
+                peer.state
+                    .is_permanently_deprioritized()
+                    .then_some(peer_id)
+                    .copied()
+            })
+            .collect()
+    }
+
     /// Attempts to restart the sync due to the stalled peer.
     ///
     /// Returns `true` if the sync is restarted with a new peer.
@@ -961,7 +1023,7 @@
                     return false;
                 }
 
-                // Pick a random peer, even if it's marked as discouraged.
+                // Pick a random peer, even if it's marked as deprioritized.
                 self.rng
                     .choice(sync_candidates)
                     .expect("Sync candidates must be non-empty as checked; qed")
@@ -973,11 +1035,11 @@
         new_peer.state = PeerSyncState::DownloadingNew { start: our_best };
 
         match &mut self.syncing {
-            Syncing::BlocksFirstSync(downloader) => {
+            Syncing::BlocksFirst(downloader) => {
                 downloader.restart(new_peer.peer_id, new_peer.best_number);
                 true
             }
-            Syncing::HeadersFirstSync(downloader) => {
+            Syncing::HeadersFirst(downloader) => {
                 downloader.restart(new_peer.peer_id, new_peer.best_number);
                 true
             }
@@ -1002,10 +1064,13 @@
         }
     }
 
-    pub(super) fn mark_peer_as_discouraged(&mut self, stalled_peer: PeerId) {
-        self.peers
-            .entry(stalled_peer)
-            .and_modify(|p| p.state = PeerSyncState::Discouraged);
+    pub(super) fn note_peer_stalled(&mut self, stalled_peer: PeerId) {
+        self.peers.entry(stalled_peer).and_modify(|p| {
+            let current_stalled_count = p.state.stalled_count();
+            p.state = PeerSyncState::Deprioritized {
+                stalled_count: current_stalled_count + 1,
+            };
+        });
     }
 
     pub(super) fn remove_peer(&mut self, peer_id: PeerId) {
@@ -1013,20 +1078,25 @@
         self.peers.remove(&peer_id);
     }
 
-    pub(super) fn set_peer_latency(&mut self, peer_id: PeerId, avg_latency: Latency) {
+    pub(super) fn update_peer_latency(&mut self, peer_id: PeerId, avg_latency: Latency) {
         self.peers.entry(peer_id).and_modify(|peer| {
-            peer.latency = PeerLatency::Ping(avg_latency);
+            peer.latency = avg_latency;
         });
+        self.update_sync_peer_on_lower_latency();
     }
 
     pub(super) fn update_sync_peer_on_lower_latency(&mut self) {
-        let current_sync_peer_id = match &self.syncing {
-            Syncing::BlocksFirstSync(downloader) => downloader.sync_peer(),
-            Syncing::HeadersFirstSync(downloader) => downloader.sync_peer(),
+        let maybe_sync_peer_id = match &self.syncing {
+            Syncing::BlocksFirst(downloader) => downloader.replaceable_sync_peer(),
+            Syncing::HeadersFirst(downloader) => downloader.replaceable_sync_peer(),
             Syncing::Idle => return,
         };
 
-        let Some(PeerLatency::Ping(current_latency)) = self
+        let Some(current_sync_peer_id) = maybe_sync_peer_id else {
+            return;
+        };
+
+        let Some(current_latency) = self
             .peers
             .get(&current_sync_peer_id)
             .map(|peer| peer.latency)
@@ -1057,27 +1127,34 @@
             return;
         };
 
-        if let PeerLatency::Ping(best_latency) = best_sync_peer.latency {
-            // Update sync peer if the latency improvement is significant.
-            if current_latency as f64 / best_latency as f64 > LATENCY_IMPROVEMENT_THRESHOLD {
-                let peer_id = best_sync_peer.peer_id;
-                let target_block_number = best_sync_peer.best_number;
-
-                match &mut self.syncing {
-                    Syncing::BlocksFirstSync(downloader) => {
-                        downloader.update_sync_peer(peer_id, target_block_number);
-                    }
-                    Syncing::HeadersFirstSync(downloader) => {
-                        downloader.update_sync_peer(peer_id, target_block_number);
-                    }
-                    Syncing::Idle => unreachable!("Must not be Idle as checked; qed"),
-                }
+        let best_latency = best_sync_peer.latency;
+
+        // Update sync peer if the latency improvement is significant.
+        if current_latency / best_latency > LATENCY_IMPROVEMENT_THRESHOLD {
+            let peer_id = best_sync_peer.peer_id;
+            let target_block_number = best_sync_peer.best_number;
+
+            let sync_peer_updated = match &mut self.syncing {
+                Syncing::BlocksFirst(downloader) => {
+                    downloader.replace_sync_peer(peer_id, target_block_number);
+                    true
+                }
+                Syncing::HeadersFirst(downloader) => {
+                    downloader.replace_sync_peer(peer_id, target_block_number);
+                    true
+                }
+                Syncing::Idle => unreachable!("Must not be Idle as checked; qed"),
+            };
 
+            if sync_peer_updated {
                 tracing::debug!(
                     old_peer_id = ?current_sync_peer_id,
                     new_peer_id = ?peer_id,
                     "🔧 Sync peer ({current_latency} ms) updated to a new peer with lower latency ({best_latency} ms)",
                 );
+                self.peers.entry(current_sync_peer_id).and_modify(|peer| {
+                    peer.state = PeerSyncState::Available;
+                });
             }
         }
     }
@@ -1087,13 +1164,13 @@
         let NewPeer {
             peer_id,
             best_number,
-            connect_latency,
+            latency,
         } = new_peer;
 
         let new_peer = PeerSync {
             peer_id,
             best_number,
-            latency: PeerLatency::Connect(connect_latency),
+            latency,
             state: PeerSyncState::Available,
         };
 
@@ -1118,66 +1195,99 @@
 
         let our_best = self.client.best_number();
 
-        let Some(best_peer) = self
-            .peers
-            .values_mut()
-            .filter(|peer| peer.best_number > our_best && peer.state.is_available())
-            .min_by_key(|peer| peer.latency)
+        let find_best_available_peer = || {
+            self.peers
+                .iter()
+                .filter(|(_peer_id, peer)| peer.best_number > our_best && peer.state.is_available())
+                .min_by_key(|(_peer_id, peer)| peer.latency)
+                .map(|(peer_id, _peer)| peer_id)
+        };
+
+        let find_best_deprioritized_peer = || {
+            self.peers
+                .iter()
+                .filter(|(_peer_id, peer)| peer.best_number > our_best)
+                .filter_map(|(peer_id, peer)| {
+                    if let PeerSyncState::Deprioritized { stalled_count } = peer.state {
+                        if stalled_count > MAX_STALLS {
+                            None
+                        } else {
+                            Some((peer_id, stalled_count, peer.latency))
+                        }
+                    } else {
+                        None
+                    }
+                })
+                .min_by(
+                    |(_, stalled_count_a, latency_a), (_, stalled_count_b, latency_b)| {
+                        // First, compare stalled_count, then latency if stalled_count is equal
+                        match stalled_count_a.cmp(stalled_count_b) {
+                            std::cmp::Ordering::Equal => latency_a.cmp(latency_b), // compare latency if stalled_count is the same
+                            other => other, // otherwise, return the comparison of stalled_count
+                        }
+                    },
+                )
+                .map(|(peer_id, _stalled_count, _latency)| peer_id)
+        };
+
+        let Some(next_peer_id) = find_best_available_peer()
+            .or_else(find_best_deprioritized_peer)
+            .copied()
         else {
             return SyncAction::None;
         };
 
-        let peer_best = best_peer.best_number;
-
-        if peer_best > our_best {
-            let sync_peer = best_peer.peer_id;
+        let Some(next_peer) = self.peers.get_mut(&next_peer_id) else {
+            return SyncAction::None;
+        };
 
-            best_peer.state = PeerSyncState::DownloadingNew { start: our_best };
+        let client = self.client.clone();
+        let peer_store = self.peer_store.clone();
 
-            let require_major_sync = peer_best - our_best > MAJOR_SYNC_GAP;
+        let peer_best = next_peer.best_number;
+        let require_major_sync = peer_best - our_best > MAJOR_SYNC_GAP;
 
-            // Start major syncing if the gap is significant.
-            let (new_syncing, sync_action) = if require_major_sync {
-                let blocks_first = our_best >= crate::checkpoint::last_checkpoint_height()
-                    || matches!(self.sync_strategy, SyncStrategy::BlocksFirst);
+        // Start major syncing if the gap is significant.
+        let (new_syncing, sync_action) = if require_major_sync {
+            let blocks_first = our_best >= crate::checkpoint::last_checkpoint_height()
+                || matches!(self.sync_strategy, SyncStrategy::BlocksFirst);
 
-                tracing::debug!(
-                    latency = ?best_peer.latency,
-                    "⏩ Starting major sync ({}) from {sync_peer:?} at #{our_best}",
-                    if blocks_first { "blocks-first" } else { "headers-first" }
-                );
+            tracing::debug!(
+                latency = ?next_peer.latency,
+                "⏩ Starting major sync ({}) from {next_peer_id:?} at #{our_best}",
+                if blocks_first { "blocks-first" } else { "headers-first" }
+            );
 
-                if blocks_first {
-                    let (downloader, blocks_request) =
-                        BlocksFirstDownloader::new(self.client.clone(), sync_peer, peer_best);
-                    (
-                        Syncing::BlocksFirstSync(Box::new(downloader)),
-                        SyncAction::Request(blocks_request),
-                    )
-                } else {
-                    let (downloader, sync_action) = HeadersFirstDownloader::new(
-                        self.client.clone(),
-                        self.header_verifier.clone(),
-                        sync_peer,
-                        peer_best,
-                    );
-                    (Syncing::HeadersFirstSync(Box::new(downloader)), sync_action)
-                }
-            } else {
+            if blocks_first {
                 let (downloader, blocks_request) =
-                    BlocksFirstDownloader::new(self.client.clone(), sync_peer, peer_best);
+                    BlocksFirstDownloader::new(client, next_peer_id, peer_best, peer_store);
                 (
-                    Syncing::BlocksFirstSync(Box::new(downloader)),
+                    Syncing::BlocksFirst(Box::new(downloader)),
                     SyncAction::Request(blocks_request),
                 )
-            };
-
-            self.update_syncing_state(new_syncing);
+            } else {
+                let (downloader, sync_action) = HeadersFirstDownloader::new(
+                    client,
+                    self.header_verifier.clone(),
+                    next_peer_id,
+                    peer_best,
+                    peer_store,
+                );
+                (Syncing::HeadersFirst(Box::new(downloader)), sync_action)
+            }
+        } else {
+            let (downloader, blocks_request) =
+                BlocksFirstDownloader::new(client, next_peer_id, peer_best, peer_store);
+            (
+                Syncing::BlocksFirst(Box::new(downloader)),
+                SyncAction::Request(blocks_request),
+            )
+        };
 
-            return sync_action;
-        }
+        next_peer.state = PeerSyncState::DownloadingNew { start: our_best };
+        self.update_syncing_state(new_syncing);
 
-        SyncAction::None
+        sync_action
     }
 
     fn update_syncing_state(&mut self, new: Syncing<Block, Client>) {
@@ -1190,7 +1300,7 @@
     pub(super) fn switch_to_idle(&mut self) {
         tracing::debug!(
             best_number = self.client.best_number(),
-            "Blocks-First sync completed, switching to Idle"
+            "Blocks-First sync completed, switching to Syncing::Idle"
         );
         self.update_syncing_state(Syncing::Idle);
     }
@@ -1215,40 +1325,44 @@
             return None;
         };
 
-        let (blocks_first_downloader, blocks_sync_request) = BlocksFirstDownloader::new(
+        let (blocks_first_downloader, blocks_request) = BlocksFirstDownloader::new(
             self.client.clone(),
             best_peer.peer_id,
             best_peer.best_number,
+            self.peer_store.clone(),
         );
 
-        tracing::debug!("Headers-first sync is complete, continuing with blocks-first sync");
-        self.update_syncing_state(Syncing::BlocksFirstSync(Box::new(blocks_first_downloader)));
+        tracing::debug!("Headers-First sync completed, continuing with blocks-first sync");
+        self.update_syncing_state(Syncing::BlocksFirst(Box::new(blocks_first_downloader)));
 
-        Some(blocks_sync_request)
+        Some(blocks_request)
     }
 
     // NOTE: `inv` can be received unsolicited as an announcement of a new block,
     // or in reply to `getblocks`.
     pub(super) fn on_inv(&mut self, inventories: Vec<Inventory>, from: PeerId) -> SyncAction {
         match &mut self.syncing {
-            Syncing::BlocksFirstSync(downloader) => downloader.on_inv(inventories, from),
-            Syncing::HeadersFirstSync(_) => SyncAction::None,
             Syncing::Idle => {
                 if inventories.len() == 1 {
                     if let Inventory::Block(block_hash) = inventories[0] {
-                        if !self.broadcasted_blocks.contains(&block_hash) {
+                        if !self.inflight_announced_blocks.contains(&block_hash) {
                             // A new block maybe broadcasted via `inv` message.
-                            return self.prepare_broadcasted_blocks_request(vec![block_hash], from);
+                            tracing::trace!(
+                                "Requesting a new block {block_hash} announced from {from:?}"
+                            );
+                            return self.announced_blocks_request(vec![block_hash], from);
                         }
                     }
                 }
                 SyncAction::None
             }
+            Syncing::BlocksFirst(downloader) => downloader.on_inv(inventories, from),
+            Syncing::HeadersFirst(_) => SyncAction::None,
         }
     }
 
     pub(super) fn on_block(&mut self, block: BitcoinBlock, from: PeerId) -> SyncAction {
-        if self.broadcasted_blocks.remove(&block.block_hash()) {
+        if self.inflight_announced_blocks.remove(&block.block_hash()) {
             self.import_queue.import_blocks(ImportBlocks {
                 origin: BlockOrigin::NetworkBroadcast,
                 blocks: vec![block],
@@ -1258,12 +1372,12 @@
 
         match &mut self.syncing {
             Syncing::Idle => SyncAction::None,
-            Syncing::BlocksFirstSync(downloader) => downloader.on_block(block, from),
-            Syncing::HeadersFirstSync(downloader) => downloader.on_block(block, from),
+            Syncing::BlocksFirst(downloader) => downloader.on_block(block, from),
+            Syncing::HeadersFirst(downloader) => downloader.on_block(block, from),
         }
     }
 
-    fn prepare_broadcasted_blocks_request(
+    fn announced_blocks_request(
         &mut self,
         block_hashes: impl IntoIterator<Item = BlockHash>,
         from: PeerId,
@@ -1272,7 +1386,7 @@
             block_hashes
                 .into_iter()
                 .map(|block_hash| {
-                    self.broadcasted_blocks.insert(block_hash);
+                    self.inflight_announced_blocks.insert(block_hash);
                     Inventory::Block(block_hash)
                 })
                 .collect(),
@@ -1284,8 +1398,8 @@
 
     pub(super) fn on_headers(&mut self, headers: Vec<BitcoinHeader>, from: PeerId) -> SyncAction {
         match &mut self.syncing {
-            Syncing::HeadersFirstSync(downloader) => downloader.on_headers(headers, from),
-            Syncing::BlocksFirstSync(_) | Syncing::Idle => {
+            Syncing::HeadersFirst(downloader) => downloader.on_headers(headers, from),
+            Syncing::BlocksFirst(_) | Syncing::Idle => {
                 if headers.is_empty() {
                     return SyncAction::None;
                 }
@@ -1299,9 +1413,7 @@
                 if headers[0].prev_blockhash == best_hash {
                     for (index, header) in headers.iter().enumerate() {
                         if !self.header_verifier.has_valid_proof_of_work(header) {
-                            tracing::error!(
-                                "Invalid header at index {index} in headers message from {from:?}"
-                            );
+                            tracing::error!(?from, "Invalid header at index {index} in headers");
                             return SyncAction::Disconnect(
                                 from,
                                 Error::BadProofOfWork(header.block_hash()),
@@ -1309,7 +1421,7 @@
                         }
                     }
 
-                    return self.prepare_broadcasted_blocks_request(
+                    return self.announced_blocks_request(
                         headers.into_iter().map(|header| header.block_hash()),
                         from,
                     );
@@ -1332,8 +1444,8 @@
     pub(super) fn on_blocks_processed(&mut self, results: ImportManyBlocksResult) {
         let download_manager = match &mut self.syncing {
             Syncing::Idle => return,
-            Syncing::BlocksFirstSync(downloader) => downloader.download_manager(),
-            Syncing::HeadersFirstSync(downloader) => downloader.download_manager(),
+            Syncing::BlocksFirst(downloader) => downloader.download_manager(),
+            Syncing::HeadersFirst(downloader) => downloader.download_manager(),
         };
         download_manager.handle_processed_blocks(results);
     }
@@ -1341,8 +1453,8 @@
     pub(super) fn import_pending_blocks(&mut self) {
         let download_manager = match &mut self.syncing {
             Syncing::Idle => return,
-            Syncing::BlocksFirstSync(downloader) => downloader.download_manager(),
-            Syncing::HeadersFirstSync(downloader) => downloader.download_manager(),
+            Syncing::BlocksFirst(downloader) => downloader.download_manager(),
+            Syncing::HeadersFirst(downloader) => downloader.download_manager(),
         };
 
         if !download_manager.has_pending_blocks() {
diff --git a/src/subcoin_network/worker.rs.html b/src/subcoin_network/worker.rs.html
index 5f80ad34..f7b0864a 100644
--- a/src/subcoin_network/worker.rs.html
+++ b/src/subcoin_network/worker.rs.html
@@ -530,17 +530,16 @@
 530
 531
 532
-533
 
use crate::connection::{ConnectionInitiator, Direction, NewConnection};
 use crate::metrics::Metrics;
 use crate::network::{
     IncomingTransaction, NetworkStatus, NetworkWorkerMessage, SendTransactionResult,
 };
-use crate::peer_manager::{Config, PeerManager, SlowPeer};
+use crate::peer_manager::{Config, NewPeer, PeerManager, SlowPeer, PEER_LATENCY_THRESHOLD};
 use crate::peer_store::PeerStore;
 use crate::sync::{ChainSync, LocatorRequest, SyncAction, SyncRequest};
 use crate::transaction_manager::TransactionManager;
-use crate::{Bandwidth, Error, Latency, PeerId, SyncStrategy};
+use crate::{Bandwidth, Error, PeerId, SyncStrategy};
 use bitcoin::p2p::message::{NetworkMessage, MAX_INV_SIZE};
 use bitcoin::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory};
 use futures::stream::FusedStream;
@@ -559,10 +558,6 @@
 /// Interval at which we perform time based maintenance
 const TICK_TIMEOUT: Duration = Duration::from_millis(1100);
 
-/// Threshold for peer latency in milliseconds, the default is 10 seconds.
-/// If a peer's latency exceeds this value, it will be considered a slow peer and may be evicted.
-const LATENCY_THRESHOLD: Latency = 10_000;
-
 /// Network event.
 #[derive(Debug)]
 pub enum Event {
@@ -592,7 +587,7 @@
     pub max_outbound_peers: usize,
     /// Whether to enable block sync on start.
     pub enable_block_sync: bool,
-    pub peer_store: PeerStore,
+    pub peer_store: Arc<dyn PeerStore>,
 }
 
 /// [`NetworkWorker`] is responsible for processing the network events.
@@ -600,7 +595,7 @@
     config: Config,
     network_event_receiver: UnboundedReceiver<Event>,
     peer_manager: PeerManager<Block, Client>,
-    peer_store: PeerStore,
+    peer_store: Arc<dyn PeerStore>,
     transaction_manager: TransactionManager,
     chain_sync: ChainSync<Block, Client>,
     metrics: Option<Metrics>,
@@ -650,6 +645,7 @@
             sync_strategy,
             is_major_syncing,
             enable_block_sync,
+            peer_store.clone(),
         );
 
         Self {
@@ -751,21 +747,20 @@
         let sync_action = self.chain_sync.on_tick();
         self.do_sync_action(sync_action);
 
-        if let Some(SlowPeer {
-            peer_id,
-            peer_latency,
-        }) = self.peer_manager.on_tick()
-        {
-            self.peer_manager
-                .disconnect(peer_id, Error::SlowPeer(peer_latency));
-            self.peer_manager.update_last_eviction();
+        for peer in self.chain_sync.unreliable_peers() {
+            self.peer_manager.disconnect(peer, Error::UnreliablePeer);
+            self.chain_sync.remove_peer(peer);
+            self.peer_store.remove_peer(peer);
+        }
+
+        if let Some(SlowPeer { peer_id, latency }) = self.peer_manager.on_tick() {
+            self.peer_manager.evict(peer_id, Error::SlowPeer(latency));
             self.chain_sync.remove_peer(peer_id);
         }
 
-        for (peer, txids) in self
-            .transaction_manager
-            .on_tick(self.peer_manager.connected_peers())
-        {
+        let connected_peers = self.peer_manager.connected_peers();
+
+        for (peer, txids) in self.transaction_manager.on_tick(connected_peers) {
             tracing::debug!("Broadcasting transaction IDs {txids:?} to {peer:?}");
             let msg = NetworkMessage::Inv(txids.into_iter().map(Inventory::Transaction).collect());
             if let Err(err) = self.send(peer, msg) {
@@ -834,16 +829,10 @@
                     tracing::debug!(?from, "Ignoring redundant verack");
                     return Ok(SyncAction::None);
                 }
-
-                let new_peer = match self.peer_manager.on_verack(from, direction) {
-                    Ok(new_peer) => new_peer,
-                    Err(err) => {
-                        self.peer_manager.disconnect(from, err);
-                        return Ok(SyncAction::None);
-                    }
-                };
-
-                Ok(self.chain_sync.add_new_peer(new_peer))
+                if let Err(err) = self.peer_manager.on_verack(from, direction) {
+                    self.peer_manager.disconnect(from, err);
+                }
+                Ok(SyncAction::None)
             }
             NetworkMessage::Addr(addresses) => {
                 self.peer_manager.on_addr(from, addresses);
@@ -885,18 +874,27 @@
             }
             NetworkMessage::Pong(nonce) => {
                 match self.peer_manager.on_pong(from, nonce) {
-                    Ok(avg_ping_latency) => {
+                    Ok(avg_latency) => {
                         // Disconnect the peer directly if the latency is higher than the threshold.
-                        if avg_ping_latency > LATENCY_THRESHOLD {
+                        if avg_latency > PEER_LATENCY_THRESHOLD {
                             self.peer_manager
-                                .disconnect(from, Error::PingLatencyTooHigh);
+                                .disconnect(from, Error::PingLatencyTooHigh(avg_latency));
                             self.chain_sync.remove_peer(from);
                             self.peer_store.remove_peer(from);
                         } else {
-                            self.chain_sync.set_peer_latency(from, avg_ping_latency);
-                            self.chain_sync.update_sync_peer_on_lower_latency();
-                            self.peer_store
-                                .add_peer_if_latency_acceptable(from, avg_ping_latency);
+                            if self.chain_sync.peers.contains_key(&from) {
+                                self.chain_sync.update_peer_latency(from, avg_latency);
+                            } else {
+                                self.chain_sync.add_new_peer(NewPeer {
+                                    peer_id: from,
+                                    best_number: self
+                                        .peer_manager
+                                        .peer_best_number(from)
+                                        .ok_or(Error::ConnectionNotFound(from))?,
+                                    latency: avg_latency,
+                                });
+                            }
+                            self.peer_store.try_add_peer(from, avg_latency);
                         }
                     }
                     Err(err) => {
@@ -956,7 +954,7 @@
                     let LocatorRequest {
                         locator_hashes,
                         stop_hash,
-                        from,
+                        to,
                     } = request;
 
                     if !locator_hashes.is_empty() {
@@ -965,15 +963,15 @@
                             locator_hashes,
                             stop_hash,
                         };
-                        let _ = self.send(from, NetworkMessage::GetHeaders(msg));
+                        let _ = self.send(to, NetworkMessage::GetHeaders(msg));
                     }
                 }
                 SyncRequest::Blocks(request) => {
                     self.send_get_blocks_request(request);
                 }
-                SyncRequest::Data(invs, from) => {
+                SyncRequest::Data(invs, to) => {
                     if !invs.is_empty() {
-                        let _ = self.send(from, NetworkMessage::GetData(invs));
+                        let _ = self.send(to, NetworkMessage::GetData(invs));
                     }
                 }
             },
@@ -989,7 +987,7 @@
             }
             SyncAction::RestartSyncWithStalledPeer(stalled_peer_id) => {
                 if self.chain_sync.restart_sync(stalled_peer_id) {
-                    self.chain_sync.mark_peer_as_discouraged(stalled_peer_id);
+                    self.chain_sync.note_peer_stalled(stalled_peer_id);
                 }
             }
             SyncAction::Disconnect(peer_id, reason) => {
@@ -1004,7 +1002,7 @@
         let LocatorRequest {
             locator_hashes,
             stop_hash,
-            from,
+            to,
         } = request;
 
         if !locator_hashes.is_empty() {
@@ -1013,7 +1011,7 @@
                 locator_hashes,
                 stop_hash,
             };
-            let _ = self.send(from, NetworkMessage::GetBlocks(msg));
+            let _ = self.send(to, NetworkMessage::GetBlocks(msg));
         }
     }
 
diff --git a/src/subcoin_node/cli/subcoin_params.rs.html b/src/subcoin_node/cli/subcoin_params.rs.html
index b06b36f8..a29b96f6 100644
--- a/src/subcoin_node/cli/subcoin_params.rs.html
+++ b/src/subcoin_node/cli/subcoin_params.rs.html
@@ -206,10 +206,10 @@
 
     /// Persistent peer latency threshold in milliseconds (ms).
     ///
-    /// Only peers with a latency lower than this threshold can be saved to disk.
+    /// Only peers with a latency lower than this threshold can possibly be saved to disk.
     ///
-    /// Default value is 200 ms
-    #[clap(long, default_value_t = 200)]
+    /// Default value is 500 ms
+    #[clap(long, default_value_t = 500)]
     pub persistent_peer_latency_threshold: u128,
 }
 
diff --git a/src/subcoin_rpc/network.rs.html b/src/subcoin_rpc/network.rs.html
index 0becffc7..c6398617 100644
--- a/src/subcoin_rpc/network.rs.html
+++ b/src/subcoin_rpc/network.rs.html
@@ -89,34 +89,66 @@
 89
 90
 91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
 
use crate::error::Error;
 use jsonrpsee::proc_macros::rpc;
 use sc_client_api::{AuxStore, BlockBackend, HeaderBackend};
 use serde::{Deserialize, Serialize};
 use sp_runtime::traits::Block as BlockT;
+use std::collections::BTreeMap;
 use std::marker::PhantomData;
 use std::sync::Arc;
 use subcoin_network::{NetworkHandle, NetworkStatus, PeerSync, PeerSyncState};
 
+/// The state of syncing between a Peer and ourselves.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
+#[serde(rename_all = "camelCase")]
+pub enum SyncState {
+    Available,
+    Deprioritized,
+    DownloadingNew,
+}
+
 #[derive(Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct NetworkPeers {
-    total: usize,
-    available: usize,
-    discouraged: usize,
-    peer_best: Option<u32>,
-    sync_peers: Vec<PeerSync>,
+    /// A map containing the count of peers in each sync state (e.g., syncing, idle).
+    sync_state_counts: BTreeMap<SyncState, usize>,
+    /// The highest block height known across all peers in the network.
+    best_known_block: Option<u32>,
+    /// Detailed synchronization information for each peer.
+    peer_sync_details: Vec<PeerSync>,
 }
 
 #[rpc(client, server)]
 pub trait NetworkApi {
-    /// Get overall network status.
-    #[method(name = "network_status")]
-    async fn network_status(&self) -> Result<Option<NetworkStatus>, Error>;
-
     /// Get the sync peers.
     #[method(name = "network_peers")]
     async fn network_peers(&self) -> Result<NetworkPeers, Error>;
+
+    /// Get overall network status.
+    #[method(name = "network_status")]
+    async fn network_status(&self) -> Result<Option<NetworkStatus>, Error>;
 }
 
 /// This struct provides the Network API.
@@ -149,30 +181,40 @@
     Client: HeaderBackend<Block> + BlockBackend<Block> + AuxStore + 'static,
 {
     async fn network_peers(&self) -> Result<NetworkPeers, Error> {
-        let sync_peers = self.network_handle.sync_peers().await;
-        let total = sync_peers.len();
+        let mut sync_peers = self.network_handle.sync_peers().await;
+
         let mut available = 0;
-        let mut discouraged = 0;
-        let mut peer_best = 0;
+        let mut deprioritized = 0;
+        let mut downloading_new = 0;
+
+        let mut best_known_block = 0;
 
         for peer in &sync_peers {
             match peer.state {
                 PeerSyncState::Available => available += 1,
-                PeerSyncState::Discouraged => discouraged += 1,
-                _ => {}
+                PeerSyncState::Deprioritized { .. } => deprioritized += 1,
+                PeerSyncState::DownloadingNew { .. } => downloading_new += 1,
             }
 
-            if peer.best_number > peer_best {
-                peer_best = peer.best_number;
+            if peer.best_number > best_known_block {
+                best_known_block = peer.best_number;
             }
         }
 
+        sync_peers.sort_by_key(|x| x.latency);
+
         Ok(NetworkPeers {
-            total,
-            available,
-            discouraged,
-            peer_best: if peer_best > 0 { Some(peer_best) } else { None },
-            sync_peers,
+            sync_state_counts: BTreeMap::from([
+                (SyncState::Available, available),
+                (SyncState::Deprioritized, deprioritized),
+                (SyncState::DownloadingNew, downloading_new),
+            ]),
+            best_known_block: if best_known_block > 0 {
+                Some(best_known_block)
+            } else {
+                None
+            },
+            peer_sync_details: sync_peers,
         })
     }
 
diff --git a/subcoin_network/all.html b/subcoin_network/all.html
index caaf8ae2..7a2dd298 100644
--- a/subcoin_network/all.html
+++ b/subcoin_network/all.html
@@ -1 +1 @@
-List of all items in this crate
\ No newline at end of file +List of all items in this crate
\ No newline at end of file diff --git a/subcoin_network/enum.Error.html b/subcoin_network/enum.Error.html index 6d2e1bad..54b767ee 100644 --- a/subcoin_network/enum.Error.html +++ b/subcoin_network/enum.Error.html @@ -1,5 +1,5 @@ -Error in subcoin_network - Rust

Enum subcoin_network::Error

source ·
pub enum Error {
-
Show 31 variants InvalidBootnode(String), +Error in subcoin_network - Rust

Enum subcoin_network::Error

source ·
pub enum Error {
+
Show 32 variants InvalidBootnode(String), PeerShutdown, NetworkEventStreamError, PeerNotFound(PeerId), @@ -17,7 +17,8 @@ HeadersNotInAscendingOrder, TooManyInventoryItems, PingTimeout, - PingLatencyTooHigh, + PingLatencyTooHigh(Latency), + UnreliablePeer, SlowPeer(Latency), UnexpectedPong, BadPong, @@ -31,7 +32,7 @@ BitcoinIO(Error), BitcoinEncoding(Error),
}
Expand description

Network error type.

-

Variants§

§

InvalidBootnode(String)

§

PeerShutdown

§

NetworkEventStreamError

§

PeerNotFound(PeerId)

§

ConnectionNotFound(PeerId)

§

ConnectionTimeout

§

UnexpectedHandshakeState(Box<HandshakeState>)

§

HandshakeTimeout

§

Ipv4Only

§

NotFullNode

§

NotSegwitNode

§

ProtocolVersionTooLow

§

BadProofOfWork(BlockHash)

§

InvHasTooManyBlockItems

§

TooManyHeaders

§

HeadersNotInAscendingOrder

§

TooManyInventoryItems

§

PingTimeout

§

PingLatencyTooHigh

§

SlowPeer(Latency)

§

UnexpectedPong

§

BadPong

§

UnrequestedBlock(BlockHash)

§

ParentOfFirstHeaderEntryNotFound

§

Other(String)

§

IO(Error)

§

InvalidAddress(AddrParseError)

§

Blockchain(Error)

§

Consensus(Error)

§

BitcoinIO(Error)

§

BitcoinEncoding(Error)

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
source§

impl From<AddrParseError> for Error

source§

fn from(source: AddrParseError) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where +

Variants§

§

InvalidBootnode(String)

§

PeerShutdown

§

NetworkEventStreamError

§

PeerNotFound(PeerId)

§

ConnectionNotFound(PeerId)

§

ConnectionTimeout

§

UnexpectedHandshakeState(Box<HandshakeState>)

§

HandshakeTimeout

§

Ipv4Only

§

NotFullNode

§

NotSegwitNode

§

ProtocolVersionTooLow

§

BadProofOfWork(BlockHash)

§

InvHasTooManyBlockItems

§

TooManyHeaders

§

HeadersNotInAscendingOrder

§

TooManyInventoryItems

§

PingTimeout

§

PingLatencyTooHigh(Latency)

§

UnreliablePeer

§

SlowPeer(Latency)

§

UnexpectedPong

§

BadPong

§

UnrequestedBlock(BlockHash)

§

ParentOfFirstHeaderEntryNotFound

§

Other(String)

§

IO(Error)

§

InvalidAddress(AddrParseError)

§

Blockchain(Error)

§

Consensus(Error)

§

BitcoinIO(Error)

§

BitcoinEncoding(Error)

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
source§

impl From<AddrParseError> for Error

source§

fn from(source: AddrParseError) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

source§

impl<T> Borrow<T> for T
where diff --git a/subcoin_network/enum.PeerLatency.html b/subcoin_network/enum.PeerLatency.html deleted file mode 100644 index 458dda3a..00000000 --- a/subcoin_network/enum.PeerLatency.html +++ /dev/null @@ -1,81 +0,0 @@ -PeerLatency in subcoin_network - Rust

Enum subcoin_network::PeerLatency

source ·
pub enum PeerLatency {
-    Connect(Latency),
-    Ping(Latency),
-}
Expand description

Letency of the peer.

-

The initial connection time is used as the baseline, the ping mechanism is -used for more accurate latency estimate after the connection is established.

-

Variants§

§

Connect(Latency)

Connection latency.

-

Only make sense for the outbound connection.

-
§

Ping(Latency)

Average ping latency.

-

Trait Implementations§

source§

impl Clone for PeerLatency

source§

fn clone(&self) -> PeerLatency

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerLatency

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for PeerLatency

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where - __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Ord for PeerLatency

source§

fn cmp(&self, other: &Self) -> CmpOrdering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where - Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where - Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where - Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for PeerLatency

source§

fn eq(&self, other: &PeerLatency) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
source§

impl PartialOrd for PeerLatency

source§

fn partial_cmp(&self, other: &Self) -> Option<CmpOrdering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the -<= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > -operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by -the >= operator. Read more
source§

impl Serialize for PeerLatency

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where - __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Copy for PeerLatency

source§

impl Eq for PeerLatency

source§

impl StructuralPartialEq for PeerLatency

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where - T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where - T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where - T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

source§

impl<T> Borrow<T> for T
where - T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where - T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CheckedConversion for T

§

fn checked_from<T>(t: T) -> Option<Self>
where - Self: TryFrom<T>,

Convert from a value of T into an equivalent instance of Option<Self>. Read more
§

fn checked_into<T>(self) -> Option<T>
where - Self: TryInto<T>,

Consume self to return Some equivalent value of Option<T>. Read more
source§

impl<T> CloneToUninit for T
where - T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> CloneToUninit for T
where - T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<Q, K> Comparable<K> for Q
where - Q: Ord + ?Sized, - K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
source§

impl<T> DynClone for T
where - T: Clone,

source§

fn __clone_box(&self, _: Private) -> *mut ()

source§

impl<Q, K> Equivalent<K> for Q
where - Q: Eq + ?Sized, - K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
§

impl<Q, K> Equivalent<K> for Q
where - Q: Eq + ?Sized, - K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where - Q: Eq + ?Sized, - K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where - Q: Eq + ?Sized, - K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

-
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an -Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an -Instrumented wrapper. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an -Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an -Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where - U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

-

That is, this conversion is whatever the implementation of -From<T> for U chooses to do.

-
source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> -if into_left is true. -Converts self into a Right variant of Either<Self, Self> -otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where - F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> -if into_left(&self) returns true. -Converts self into a Right variant of Either<Self, Self> -otherwise. Read more
§

impl<T, Outer> IsWrappedBy<Outer> for T
where - Outer: AsRef<T> + AsMut<T> + From<T>, - T: From<Outer>,

§

fn from_ref(outer: &Outer) -> &T

Get a reference to the inner from the outer.

-
§

fn from_mut(outer: &mut Outer) -> &mut T

Get a mutable reference to the inner from the outer.

-
§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> SaturatedConversion for T

§

fn saturated_from<T>(t: T) -> Self
where - Self: UniqueSaturatedFrom<T>,

Convert from a value of T into an equivalent instance of Self. Read more
§

fn saturated_into<T>(self) -> T
where - Self: UniqueSaturatedInto<T>,

Consume self to return an equivalent value of T. Read more
source§

impl<T> ToOwned for T
where - T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where - U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where - U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T> UncheckedInto<T> for S
where - T: UncheckedFrom<S>,

§

fn unchecked_into(self) -> T

The counterpart to unchecked_from.
§

impl<T, S> UniqueSaturatedInto<T> for S
where - T: Bounded, - S: TryInto<T>,

§

fn unique_saturated_into(self) -> T

Consume self to return an equivalent value of T.
§

impl<V, T> VZip<V> for T
where - V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where - S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a -[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a -[WithDispatch] wrapper. Read more
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where - S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a -WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a -WithDispatch wrapper. Read more
source§

impl<T> DeserializeOwned for T
where - T: for<'de> Deserialize<'de>,

§

impl<T> JsonSchemaMaybe for T

§

impl<T> MaybeDebug for T
where - T: Debug,

§

impl<T> MaybeRefUnwindSafe for T
where - T: RefUnwindSafe,

§

impl<T> MaybeSend for T
where - T: Send,

§

impl<T> MaybeSerialize for T
where - T: Serialize,

§

impl<T> MaybeSerializeDeserialize for T

§

impl<T> Member for T
where - T: Send + Sync + Debug + Eq + PartialEq + Clone + 'static,

\ No newline at end of file diff --git a/subcoin_network/enum.PeerSyncState.html b/subcoin_network/enum.PeerSyncState.html index 277f0864..b164c4b3 100644 --- a/subcoin_network/enum.PeerSyncState.html +++ b/subcoin_network/enum.PeerSyncState.html @@ -1,18 +1,23 @@ -PeerSyncState in subcoin_network - Rust

Enum subcoin_network::PeerSyncState

source ·
pub enum PeerSyncState {
+PeerSyncState in subcoin_network - Rust

Enum subcoin_network::PeerSyncState

source ·
pub enum PeerSyncState {
     Available,
-    Discouraged,
+    Deprioritized {
+        stalled_count: usize,
+    },
     DownloadingNew {
         start: u32,
     },
 }
Expand description

The state of syncing between a Peer and ourselves.

Variants§

§

Available

Available for sync requests.

-
§

Discouraged

The peer has been discouraged due to syncing from this peer was stalled before.

-
§

DownloadingNew

Actively downloading new blocks, starting from the given Number.

-

Fields

§start: u32

Implementations§

source§

impl PeerSyncState

source

pub fn is_available(&self) -> bool

Returns true if the peer is available for syncing.

-

Trait Implementations§

source§

impl Clone for PeerSyncState

source§

fn clone(&self) -> PeerSyncState

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerSyncState

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for PeerSyncState

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where - __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl PartialEq for PeerSyncState

source§

fn eq(&self, other: &PeerSyncState) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
source§

impl Serialize for PeerSyncState

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where - __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Copy for PeerSyncState

source§

impl Eq for PeerSyncState

source§

impl StructuralPartialEq for PeerSyncState

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where +
§

Deprioritized

The peer has been deprioritized due to past syncing issues (e.g., stalling).

+

Fields

§stalled_count: usize

Number of times the peer has stalled.

+
§

DownloadingNew

Actively downloading new blocks, starting from the given Number.

+

Fields

§start: u32

Implementations§

source§

impl PeerSyncState

source

pub fn is_available(&self) -> bool

Returns true if the peer is available for syncing.

+

Trait Implementations§

source§

impl Clone for PeerSyncState

source§

fn clone(&self) -> PeerSyncState

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerSyncState

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for PeerSyncState

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for PeerSyncState

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for PeerSyncState

source§

fn eq(&self, other: &PeerSyncState) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
source§

impl Serialize for PeerSyncState

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Copy for PeerSyncState

source§

impl Eq for PeerSyncState

source§

impl StructuralPartialEq for PeerSyncState

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

source§

impl<T> Borrow<T> for T
where @@ -66,10 +71,15 @@ S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more

source§

impl<T> DeserializeOwned for T
where - T: for<'de> Deserialize<'de>,

§

impl<T> JsonSchemaMaybe for T

§

impl<T> MaybeDebug for T
where - T: Debug,

§

impl<T> MaybeRefUnwindSafe for T
where + T: for<'de> Deserialize<'de>,

§

impl<T> ExHashT for T
where + T: Hash + Eq + Debug + Clone + Send + Sync + 'static,

§

impl<T> JsonSchemaMaybe for T

§

impl<T> MaybeDebug for T
where + T: Debug,

§

impl<T> MaybeHash for T
where + T: Hash,

§

impl<T> MaybeHash for T
where + T: Hash,

§

impl<T> MaybeRefUnwindSafe for T
where T: RefUnwindSafe,

§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> MaybeSerialize for T
where T: Serialize,

§

impl<T> MaybeSerializeDeserialize for T

§

impl<T> Member for T
where - T: Send + Sync + Debug + Eq + PartialEq + Clone + 'static,

\ No newline at end of file + T: Send + Sync + Debug + Eq + PartialEq + Clone + 'static,
§

impl<T> Sequence for T
where + T: Eq + Hash,

§

impl<K> SubstreamSetKey for K
where + K: Hash + Unpin + Debug + PartialEq + Eq + Copy,

\ No newline at end of file diff --git a/subcoin_network/enum.SyncStrategy.html b/subcoin_network/enum.SyncStrategy.html index 9563c565..45c21abc 100644 --- a/subcoin_network/enum.SyncStrategy.html +++ b/subcoin_network/enum.SyncStrategy.html @@ -1,10 +1,10 @@ -SyncStrategy in subcoin_network - Rust

Enum subcoin_network::SyncStrategy

source ·
pub enum SyncStrategy {
+SyncStrategy in subcoin_network - Rust

Enum subcoin_network::SyncStrategy

source ·
pub enum SyncStrategy {
     HeadersFirst,
     BlocksFirst,
 }
Expand description

Represents the strategy for block syncing.

Variants§

§

HeadersFirst

Download the headers first, followed by the block bodies.

§

BlocksFirst

Download the full blocks (both headers and bodies) in sequence.

-

Trait Implementations§

source§

impl Clone for SyncStrategy

source§

fn clone(&self) -> SyncStrategy

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for SyncStrategy

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for SyncStrategy

source§

fn default() -> SyncStrategy

Returns the “default value” for a type. Read more
source§

impl ValueEnum for SyncStrategy

source§

fn value_variants<'a>() -> &'a [Self]

All possible argument values, in display order.
source§

fn to_possible_value<'a>(&self) -> Option<PossibleValue>

The canonical argument value. Read more
§

fn from_str(input: &str, ignore_case: bool) -> Result<Self, String>

Parse an argument into Self.
source§

impl Copy for SyncStrategy

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where +

Trait Implementations§

source§

impl Clone for SyncStrategy

source§

fn clone(&self) -> SyncStrategy

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for SyncStrategy

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for SyncStrategy

source§

fn default() -> SyncStrategy

Returns the “default value” for a type. Read more
source§

impl ValueEnum for SyncStrategy

source§

fn value_variants<'a>() -> &'a [Self]

All possible argument values, in display order.
source§

fn to_possible_value<'a>(&self) -> Option<PossibleValue>

The canonical argument value. Read more
§

fn from_str(input: &str, ignore_case: bool) -> Result<Self, String>

Parse an argument into Self.
source§

impl Copy for SyncStrategy

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

source§

impl<T> Borrow<T> for T
where diff --git a/subcoin_network/index.html b/subcoin_network/index.html index fcb3dfc4..7f64205d 100644 --- a/subcoin_network/index.html +++ b/subcoin_network/index.html @@ -1,4 +1,4 @@ -subcoin_network - Rust

Crate subcoin_network

source ·
Expand description

§Bitcoin Network

+subcoin_network - Rust

Crate subcoin_network

source ·
Expand description

§Bitcoin Network

This crate facilitates communication with other nodes in the Bitcoin P2P network. It handles connections, message transmission, and the peer-to-peer protocol.

§Initial Block Download

@@ -23,4 +23,4 @@

Structs§

  • Network configuration.
  • Represents the Subcoin network component.
  • A handle for interacting with the network worker.
  • Represents the status of network.
  • Contains all the data about a Peer that we are trying to sync with.

Enums§

Type Aliases§

\ No newline at end of file +

Structs§

  • Network configuration.
  • Represents the Subcoin network component.
  • A handle for interacting with the network worker.
  • Represents the status of network.
  • Contains all the data about a Peer that we are trying to sync with.

Enums§

Type Aliases§

\ No newline at end of file diff --git a/subcoin_network/sidebar-items.js b/subcoin_network/sidebar-items.js index a142e1ab..82914f9f 100644 --- a/subcoin_network/sidebar-items.js +++ b/subcoin_network/sidebar-items.js @@ -1 +1 @@ -window.SIDEBAR_ITEMS = {"enum":["Error","PeerLatency","PeerSyncState","SendTransactionResult","SyncStatus","SyncStrategy"],"struct":["Config","Network","NetworkHandle","NetworkStatus","PeerSync"],"type":["Latency","PeerId"]}; \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":["Error","PeerSyncState","SendTransactionResult","SyncStatus","SyncStrategy"],"struct":["Config","Network","NetworkHandle","NetworkStatus","PeerSync"],"type":["Latency","PeerId"]}; \ No newline at end of file diff --git a/subcoin_network/struct.Config.html b/subcoin_network/struct.Config.html index 34deb541..577383af 100644 --- a/subcoin_network/struct.Config.html +++ b/subcoin_network/struct.Config.html @@ -1,4 +1,4 @@ -Config in subcoin_network - Rust

Struct subcoin_network::Config

source ·
pub struct Config {
+Config in subcoin_network - Rust

Struct subcoin_network::Config

source ·
pub struct Config {
     pub network: Network,
     pub base_path: PathBuf,
     pub listen_on: PeerId,
diff --git a/subcoin_network/struct.Network.html b/subcoin_network/struct.Network.html
index ae06be67..9762cc48 100644
--- a/subcoin_network/struct.Network.html
+++ b/subcoin_network/struct.Network.html
@@ -1,14 +1,14 @@
-Network in subcoin_network - Rust

Struct subcoin_network::Network

source ·
pub struct Network<Block, Client> { /* private fields */ }
Expand description

Represents the Subcoin network component.

-

Implementations§

source§

impl<Block, Client> Network<Block, Client>
where +Network in subcoin_network - Rust

Struct subcoin_network::Network

source ·
pub struct Network<Block, Client> { /* private fields */ }
Expand description

Represents the Subcoin network component.

+

Implementations§

source§

impl<Block, Client> Network<Block, Client>
where Block: BlockT, - Client: HeaderBackend<Block> + AuxStore,

source

pub fn new( + Client: HeaderBackend<Block> + AuxStore,

source

pub fn new( client: Arc<Client>, config: Config, import_queue: BlockImportQueue, spawn_handle: SpawnTaskHandle, registry: Option<Registry>, ) -> (Self, NetworkHandle)

Constructs a new instance of Network.

-
source

pub async fn run(self) -> Result<(), Error>

Starts the network.

+
source

pub async fn run(self) -> Result<(), Error>

Starts the network.

This must be run in a background task.

Auto Trait Implementations§

§

impl<Block, Client> Freeze for Network<Block, Client>

§

impl<Block, Client> !RefUnwindSafe for Network<Block, Client>

§

impl<Block, Client> Send for Network<Block, Client>
where Client: Sync + Send, diff --git a/subcoin_network/struct.PeerSync.html b/subcoin_network/struct.PeerSync.html index 5d08f4d3..11939f9f 100644 --- a/subcoin_network/struct.PeerSync.html +++ b/subcoin_network/struct.PeerSync.html @@ -1,16 +1,16 @@ -PeerSync in subcoin_network - Rust

Struct subcoin_network::PeerSync

source ·
pub struct PeerSync {
+PeerSync in subcoin_network - Rust

Struct subcoin_network::PeerSync

source ·
pub struct PeerSync {
     pub peer_id: PeerId,
     pub best_number: u32,
-    pub latency: PeerLatency,
+    pub latency: Latency,
     pub state: PeerSyncState,
 }
Expand description

Contains all the data about a Peer that we are trying to sync with.

Fields§

§peer_id: PeerId

Peer id of this peer.

§best_number: u32

The number of the best block that we’ve seen for this peer.

-
§latency: PeerLatency

Latency of connection to this peer.

+
§latency: Latency

Latency of connection to this peer.

§state: PeerSyncState

The state of syncing this peer is in for us, generally categories into Available or “busy” with something as defined by PeerSyncState.

-

Trait Implementations§

source§

impl Clone for PeerSync

source§

fn clone(&self) -> PeerSync

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerSync

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for PeerSync

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where - __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Serialize for PeerSync

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where +

Trait Implementations§

source§

impl Clone for PeerSync

source§

fn clone(&self) -> PeerSync

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerSync

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for PeerSync

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Serialize for PeerSync

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where diff --git a/subcoin_network/sync/enum.PeerLatency.html b/subcoin_network/sync/enum.PeerLatency.html deleted file mode 100644 index f96b4e22..00000000 --- a/subcoin_network/sync/enum.PeerLatency.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Redirection - - -

Redirecting to ../../subcoin_network/enum.PeerLatency.html...

- - - \ No newline at end of file diff --git a/trait.impl/core/clone/trait.Clone.js b/trait.impl/core/clone/trait.Clone.js index 8edbff22..dd05c984 100644 --- a/trait.impl/core/clone/trait.Clone.js +++ b/trait.impl/core/clone/trait.Clone.js @@ -2,7 +2,7 @@ "pallet_bitcoin":[["impl Clone for LockTime"],["impl Clone for TxIn"],["impl Clone for OutPoint"],["impl Clone for RegularTxIn"],["impl Clone for Transaction"],["impl Clone for TxOut"],["impl Clone for Txid"],["impl Clone for Witness"],["impl<T> Clone for Pallet<T>"],["impl<T: Config> Clone for Call<T>"],["impl<T: Config> Clone for Event<T>"]], "sc_consensus_nakamoto":[["impl Clone for BlockVerification"],["impl Clone for ImportStatus"],["impl Clone for ChainParams"],["impl Clone for ImportBlocks"],["impl Clone for ImportConfig"],["impl<Block, Client> Clone for HeaderVerifier<Block, Client>"],["impl<Block: Clone, Client: Clone, BE: Clone> Clone for BlockVerifier<Block, Client, BE>"]], "subcoin_crypto":[["impl Clone for MuHash3072"]], -"subcoin_network":[["impl Clone for PeerLatency"],["impl Clone for PeerSyncState"],["impl Clone for SendTransactionResult"],["impl Clone for SyncStatus"],["impl Clone for SyncStrategy"],["impl Clone for NetworkHandle"],["impl Clone for NetworkStatus"],["impl Clone for PeerSync"]], +"subcoin_network":[["impl Clone for PeerSyncState"],["impl Clone for SendTransactionResult"],["impl Clone for SyncStatus"],["impl Clone for SyncStrategy"],["impl Clone for NetworkHandle"],["impl Clone for NetworkStatus"],["impl Clone for PeerSync"]], "subcoin_primitives":[["impl Clone for HeaderError"],["impl Clone for BlockLocator"],["impl Clone for IndexedBlock"]], "subcoin_runtime":[["impl Clone for OriginCaller"],["impl Clone for RuntimeCall"],["impl Clone for RuntimeEvent"],["impl Clone for RuntimeTask"],["impl Clone for Runtime"],["impl Clone for RuntimeOrigin"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Eq.js b/trait.impl/core/cmp/trait.Eq.js index 55ed4865..986b2d9a 100644 --- a/trait.impl/core/cmp/trait.Eq.js +++ b/trait.impl/core/cmp/trait.Eq.js @@ -2,6 +2,6 @@ "pallet_bitcoin":[["impl<T> Eq for Pallet<T>"],["impl<T: Config> Eq for Call<T>"],["impl<T: Config> Eq for Event<T>"]], "sc_consensus_nakamoto":[["impl Eq for BlockVerification"]], "subcoin_crypto":[["impl Eq for MuHash3072"]], -"subcoin_network":[["impl Eq for PeerLatency"],["impl Eq for PeerSyncState"]], +"subcoin_network":[["impl Eq for PeerSyncState"]], "subcoin_runtime":[["impl Eq for OriginCaller"],["impl Eq for RuntimeCall"],["impl Eq for RuntimeEvent"],["impl Eq for RuntimeTask"],["impl Eq for Runtime"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Ord.js b/trait.impl/core/cmp/trait.Ord.js index ecfb8d83..7296248d 100644 --- a/trait.impl/core/cmp/trait.Ord.js +++ b/trait.impl/core/cmp/trait.Ord.js @@ -1,4 +1,3 @@ (function() {var implementors = { -"subcoin_crypto":[["impl Ord for MuHash3072"]], -"subcoin_network":[["impl Ord for PeerLatency"]] +"subcoin_crypto":[["impl Ord for MuHash3072"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialEq.js b/trait.impl/core/cmp/trait.PartialEq.js index 8019ef17..87f42dbc 100644 --- a/trait.impl/core/cmp/trait.PartialEq.js +++ b/trait.impl/core/cmp/trait.PartialEq.js @@ -2,6 +2,6 @@ "pallet_bitcoin":[["impl PartialEq for LockTime"],["impl PartialEq for TxIn"],["impl PartialEq for OutPoint"],["impl PartialEq for RegularTxIn"],["impl PartialEq for Transaction"],["impl PartialEq for TxOut"],["impl PartialEq for Txid"],["impl PartialEq for Witness"],["impl<T> PartialEq for Pallet<T>"],["impl<T: Config> PartialEq for Call<T>"],["impl<T: Config> PartialEq for Event<T>"]], "sc_consensus_nakamoto":[["impl PartialEq for BlockVerification"]], "subcoin_crypto":[["impl PartialEq for MuHash3072"]], -"subcoin_network":[["impl PartialEq for PeerLatency"],["impl PartialEq for PeerSyncState"]], +"subcoin_network":[["impl PartialEq for PeerSyncState"]], "subcoin_runtime":[["impl PartialEq for OriginCaller"],["impl PartialEq for RuntimeCall"],["impl PartialEq for RuntimeEvent"],["impl PartialEq for RuntimeTask"],["impl PartialEq for Runtime"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialOrd.js b/trait.impl/core/cmp/trait.PartialOrd.js index f554d3e7..02165a77 100644 --- a/trait.impl/core/cmp/trait.PartialOrd.js +++ b/trait.impl/core/cmp/trait.PartialOrd.js @@ -1,4 +1,3 @@ (function() {var implementors = { -"subcoin_crypto":[["impl PartialOrd for MuHash3072"]], -"subcoin_network":[["impl PartialOrd for PeerLatency"]] +"subcoin_crypto":[["impl PartialOrd for MuHash3072"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js index 099bf32b..7b7d3d8d 100644 --- a/trait.impl/core/fmt/trait.Debug.js +++ b/trait.impl/core/fmt/trait.Debug.js @@ -2,7 +2,7 @@ "pallet_bitcoin":[["impl Debug for LockTime"],["impl Debug for TxIn"],["impl Debug for OutPoint"],["impl Debug for RegularTxIn"],["impl Debug for Transaction"],["impl Debug for TxOut"],["impl Debug for Txid"],["impl Debug for Witness"],["impl<T> Debug for Pallet<T>"],["impl<T: Config> Debug for Call<T>"],["impl<T: Config> Debug for Event<T>"]], "sc_consensus_nakamoto":[["impl Debug for BlockVerification"],["impl Debug for Error"],["impl Debug for Error"],["impl Debug for ImportStatus"],["impl Debug for BlockImportQueue"],["impl Debug for ChainParams"],["impl Debug for ImportBlocks"],["impl Debug for ImportConfig"],["impl Debug for ImportManyBlocksResult"]], "subcoin_crypto":[["impl Debug for MuHash3072"]], -"subcoin_network":[["impl Debug for Error"],["impl Debug for PeerLatency"],["impl Debug for PeerSyncState"],["impl Debug for SendTransactionResult"],["impl Debug for SyncStatus"],["impl Debug for SyncStrategy"],["impl Debug for NetworkHandle"],["impl Debug for NetworkStatus"],["impl Debug for PeerSync"]], +"subcoin_network":[["impl Debug for Error"],["impl Debug for PeerSyncState"],["impl Debug for SendTransactionResult"],["impl Debug for SyncStatus"],["impl Debug for SyncStrategy"],["impl Debug for NetworkHandle"],["impl Debug for NetworkStatus"],["impl Debug for PeerSync"]], "subcoin_primitives":[["impl Debug for HeaderError"],["impl Debug for BlockLocator"],["impl Debug for IndexedBlock"]], "subcoin_runtime":[["impl Debug for OriginCaller"],["impl Debug for RuntimeCall"],["impl Debug for RuntimeError"],["impl Debug for RuntimeEvent"],["impl Debug for RuntimeTask"],["impl Debug for Runtime"],["impl Debug for RuntimeOrigin"]], "subcoin_runtime_primitives":[["impl Debug for Coin"]] diff --git a/trait.impl/core/hash/trait.Hash.js b/trait.impl/core/hash/trait.Hash.js new file mode 100644 index 00000000..34edf0c7 --- /dev/null +++ b/trait.impl/core/hash/trait.Hash.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"subcoin_network":[["impl Hash for PeerSyncState"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Copy.js b/trait.impl/core/marker/trait.Copy.js index be2c5383..4871a2f4 100644 --- a/trait.impl/core/marker/trait.Copy.js +++ b/trait.impl/core/marker/trait.Copy.js @@ -1,7 +1,7 @@ (function() {var implementors = { "pallet_bitcoin":[["impl Copy for Txid"]], "sc_consensus_nakamoto":[["impl Copy for BlockVerification"]], -"subcoin_network":[["impl Copy for PeerLatency"],["impl Copy for PeerSyncState"],["impl Copy for SyncStrategy"]], +"subcoin_network":[["impl Copy for PeerSyncState"],["impl Copy for SyncStrategy"]], "subcoin_primitives":[["impl Copy for IndexedBlock"]], "subcoin_runtime":[["impl Copy for Runtime"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js index d44b02ec..2e3c0bd1 100644 --- a/trait.impl/core/marker/trait.Freeze.js +++ b/trait.impl/core/marker/trait.Freeze.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> Freeze for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl Freeze for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl Freeze for Error",1,["sc_consensus_nakamoto::Error"]],["impl Freeze for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl Freeze for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl Freeze for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl Freeze for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl Freeze for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl Freeze for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl Freeze for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl<Block, Client> Freeze for HeaderVerifier<Block, Client>",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> Freeze for SubstrateImportQueueVerifier<Block, Client>",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> Freeze for BlockVerifier<Block, Client, BE>",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> Freeze for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>
where\n BI: Freeze,
",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl Freeze for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl Freeze for Error",1,["subcoin_network::Error"]],["impl Freeze for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl Freeze for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Freeze for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Freeze for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Freeze for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Freeze for Config",1,["subcoin_network::Config"]],["impl Freeze for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Freeze for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Freeze for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Freeze for Network<Block, Client>",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl Freeze for Error",1,["subcoin_network::Error"]],["impl Freeze for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Freeze for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Freeze for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Freeze for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Freeze for Config",1,["subcoin_network::Config"]],["impl Freeze for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Freeze for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Freeze for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Freeze for Network<Block, Client>",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl Freeze for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl Freeze for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl Freeze for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> Freeze for SubcoinRpc<Block, Client, TransactionAdapter>",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl Freeze for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl Freeze for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl Freeze for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl Freeze for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl Freeze for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl Freeze for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl Freeze for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl Freeze for Runtime",1,["subcoin_runtime::Runtime"]],["impl Freeze for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl Freeze for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl Freeze for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl Freeze for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> !Freeze for RuntimeApiImpl<Block, C>",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js index 9ba4110b..7c30d8d5 100644 --- a/trait.impl/core/marker/trait.Send.js +++ b/trait.impl/core/marker/trait.Send.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> Send for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>
where\n System: Send,\n Block: Send,\n Context: Send,\n UnsignedValidator: Send,\n AllPalletsWithSystem: Send,\n OnRuntimeUpgrade: Send,
",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl Send for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl Send for Error",1,["sc_consensus_nakamoto::Error"]],["impl Send for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl Send for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl Send for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl Send for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl Send for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl Send for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl Send for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl<Block, Client> Send for HeaderVerifier<Block, Client>
where\n Client: Sync + Send,\n Block: Send,
",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> Send for SubstrateImportQueueVerifier<Block, Client>
where\n Client: Sync + Send,\n Block: Send,
",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> Send for BlockVerifier<Block, Client, BE>
where\n Client: Sync + Send,\n Block: Send,\n BE: Send,
",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> Send for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>
where\n BI: Send,\n Client: Sync + Send,\n TransactionAdapter: Send,\n Block: Send,\n BE: Send,
",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl Send for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl Send for Error",1,["subcoin_network::Error"]],["impl Send for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl Send for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Send for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Send for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Send for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Send for Config",1,["subcoin_network::Config"]],["impl Send for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Send for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Send for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Send for Network<Block, Client>
where\n Client: Sync + Send,\n Block: Send,
",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl Send for Error",1,["subcoin_network::Error"]],["impl Send for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Send for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Send for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Send for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Send for Config",1,["subcoin_network::Config"]],["impl Send for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Send for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Send for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Send for Network<Block, Client>
where\n Client: Sync + Send,\n Block: Send,
",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl Send for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl Send for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl Send for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> Send for SubcoinRpc<Block, Client, TransactionAdapter>
where\n Client: Sync + Send,\n Block: Send,\n TransactionAdapter: Send,
",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl !Send for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl Send for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl Send for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl Send for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl Send for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl Send for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl Send for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl Send for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl Send for Runtime",1,["subcoin_runtime::Runtime"]],["impl Send for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl Send for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl Send for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> Send for RuntimeApiImpl<Block, C>
where\n C: Sync,
",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/core/marker/trait.StructuralPartialEq.js b/trait.impl/core/marker/trait.StructuralPartialEq.js index 4fc81e82..79c0a682 100644 --- a/trait.impl/core/marker/trait.StructuralPartialEq.js +++ b/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -2,6 +2,6 @@ "pallet_bitcoin":[["impl StructuralPartialEq for LockTime"],["impl StructuralPartialEq for TxIn"],["impl StructuralPartialEq for OutPoint"],["impl StructuralPartialEq for RegularTxIn"],["impl StructuralPartialEq for Transaction"],["impl StructuralPartialEq for TxOut"],["impl StructuralPartialEq for Txid"],["impl StructuralPartialEq for Witness"]], "sc_consensus_nakamoto":[["impl StructuralPartialEq for BlockVerification"]], "subcoin_crypto":[["impl StructuralPartialEq for MuHash3072"]], -"subcoin_network":[["impl StructuralPartialEq for PeerLatency"],["impl StructuralPartialEq for PeerSyncState"]], +"subcoin_network":[["impl StructuralPartialEq for PeerSyncState"]], "subcoin_runtime":[["impl StructuralPartialEq for OriginCaller"],["impl StructuralPartialEq for RuntimeCall"],["impl StructuralPartialEq for RuntimeEvent"],["impl StructuralPartialEq for RuntimeTask"],["impl StructuralPartialEq for Runtime"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js index 1ac5536d..3fc16051 100644 --- a/trait.impl/core/marker/trait.Sync.js +++ b/trait.impl/core/marker/trait.Sync.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> Sync for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>
where\n System: Sync,\n Block: Sync,\n Context: Sync,\n UnsignedValidator: Sync,\n AllPalletsWithSystem: Sync,\n OnRuntimeUpgrade: Sync,
",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl Sync for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl Sync for Error",1,["sc_consensus_nakamoto::Error"]],["impl Sync for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl Sync for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl Sync for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl Sync for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl Sync for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl Sync for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl Sync for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl<Block, Client> Sync for HeaderVerifier<Block, Client>
where\n Client: Sync + Send,\n Block: Sync,
",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> Sync for SubstrateImportQueueVerifier<Block, Client>
where\n Client: Sync + Send,\n Block: Sync,
",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> Sync for BlockVerifier<Block, Client, BE>
where\n Client: Sync + Send,\n Block: Sync,\n BE: Sync,
",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> Sync for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>
where\n BI: Sync,\n Client: Sync + Send,\n TransactionAdapter: Sync,\n Block: Sync,\n BE: Sync,
",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl Sync for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl Sync for Error",1,["subcoin_network::Error"]],["impl Sync for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl Sync for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Sync for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Sync for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Sync for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Sync for Config",1,["subcoin_network::Config"]],["impl Sync for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Sync for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Sync for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Sync for Network<Block, Client>
where\n Client: Sync + Send,\n Block: Sync,
",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl Sync for Error",1,["subcoin_network::Error"]],["impl Sync for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Sync for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Sync for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Sync for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Sync for Config",1,["subcoin_network::Config"]],["impl Sync for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Sync for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Sync for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Sync for Network<Block, Client>
where\n Client: Sync + Send,\n Block: Sync,
",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl Sync for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl Sync for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl Sync for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> Sync for SubcoinRpc<Block, Client, TransactionAdapter>
where\n Client: Sync + Send,\n Block: Sync,\n TransactionAdapter: Sync,
",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl !Sync for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl Sync for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl Sync for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl Sync for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl Sync for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl Sync for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl Sync for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl Sync for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl Sync for Runtime",1,["subcoin_runtime::Runtime"]],["impl Sync for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl Sync for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl Sync for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> !Sync for RuntimeApiImpl<Block, C>",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js index f7760d8b..35665b19 100644 --- a/trait.impl/core/marker/trait.Unpin.js +++ b/trait.impl/core/marker/trait.Unpin.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> Unpin for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>
where\n System: Unpin,\n Block: Unpin,\n Context: Unpin,\n UnsignedValidator: Unpin,\n AllPalletsWithSystem: Unpin,\n OnRuntimeUpgrade: Unpin,
",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl Unpin for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl Unpin for Error",1,["sc_consensus_nakamoto::Error"]],["impl Unpin for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl Unpin for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl Unpin for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl Unpin for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl Unpin for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl Unpin for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl Unpin for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl<Block, Client> Unpin for HeaderVerifier<Block, Client>
where\n Block: Unpin,
",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> Unpin for SubstrateImportQueueVerifier<Block, Client>
where\n Block: Unpin,
",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> Unpin for BlockVerifier<Block, Client, BE>
where\n Block: Unpin,\n BE: Unpin,
",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> Unpin for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>
where\n BI: Unpin,\n TransactionAdapter: Unpin,\n Block: Unpin,\n BE: Unpin,
",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl Unpin for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl Unpin for Error",1,["subcoin_network::Error"]],["impl Unpin for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl Unpin for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Unpin for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Unpin for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Unpin for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Unpin for Config",1,["subcoin_network::Config"]],["impl Unpin for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Unpin for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Unpin for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Unpin for Network<Block, Client>
where\n Block: Unpin,
",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl Unpin for Error",1,["subcoin_network::Error"]],["impl Unpin for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl Unpin for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl Unpin for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl Unpin for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl Unpin for Config",1,["subcoin_network::Config"]],["impl Unpin for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl Unpin for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl Unpin for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> Unpin for Network<Block, Client>
where\n Block: Unpin,
",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl Unpin for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl Unpin for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl Unpin for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> Unpin for SubcoinRpc<Block, Client, TransactionAdapter>
where\n Block: Unpin,\n TransactionAdapter: Unpin,
",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl Unpin for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl Unpin for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl Unpin for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl Unpin for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl Unpin for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl Unpin for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl Unpin for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl Unpin for Runtime",1,["subcoin_runtime::Runtime"]],["impl Unpin for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl Unpin for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl Unpin for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl Unpin for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> Unpin for RuntimeApiImpl<Block, C>
where\n <Block as Block>::Hash: Unpin,\n <<Block as Block>::Header as Header>::Hashing: Unpin,
",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js index cfc6aff7..b9e4c6db 100644 --- a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> RefUnwindSafe for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>
where\n System: RefUnwindSafe,\n Block: RefUnwindSafe,\n Context: RefUnwindSafe,\n UnsignedValidator: RefUnwindSafe,\n AllPalletsWithSystem: RefUnwindSafe,\n OnRuntimeUpgrade: RefUnwindSafe,
",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl !RefUnwindSafe for Error",1,["sc_consensus_nakamoto::Error"]],["impl !RefUnwindSafe for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl !RefUnwindSafe for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl RefUnwindSafe for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl RefUnwindSafe for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl RefUnwindSafe for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl RefUnwindSafe for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl RefUnwindSafe for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl RefUnwindSafe for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl<Block, Client> RefUnwindSafe for HeaderVerifier<Block, Client>
where\n Block: RefUnwindSafe,\n Client: RefUnwindSafe,
",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> RefUnwindSafe for SubstrateImportQueueVerifier<Block, Client>
where\n Block: RefUnwindSafe,\n Client: RefUnwindSafe,
",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> !RefUnwindSafe for BlockVerifier<Block, Client, BE>",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> !RefUnwindSafe for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl RefUnwindSafe for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl !RefUnwindSafe for Error",1,["subcoin_network::Error"]],["impl RefUnwindSafe for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl RefUnwindSafe for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl RefUnwindSafe for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl RefUnwindSafe for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl RefUnwindSafe for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl RefUnwindSafe for Config",1,["subcoin_network::Config"]],["impl RefUnwindSafe for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl RefUnwindSafe for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl RefUnwindSafe for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> !RefUnwindSafe for Network<Block, Client>",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl !RefUnwindSafe for Error",1,["subcoin_network::Error"]],["impl RefUnwindSafe for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl RefUnwindSafe for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl RefUnwindSafe for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl RefUnwindSafe for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl RefUnwindSafe for Config",1,["subcoin_network::Config"]],["impl RefUnwindSafe for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl RefUnwindSafe for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl RefUnwindSafe for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> !RefUnwindSafe for Network<Block, Client>",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl RefUnwindSafe for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl RefUnwindSafe for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl RefUnwindSafe for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> RefUnwindSafe for SubcoinRpc<Block, Client, TransactionAdapter>
where\n Block: RefUnwindSafe,\n TransactionAdapter: RefUnwindSafe,\n Client: RefUnwindSafe,
",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl !RefUnwindSafe for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl RefUnwindSafe for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl RefUnwindSafe for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl RefUnwindSafe for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl RefUnwindSafe for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl RefUnwindSafe for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl RefUnwindSafe for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl RefUnwindSafe for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl RefUnwindSafe for Runtime",1,["subcoin_runtime::Runtime"]],["impl RefUnwindSafe for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl RefUnwindSafe for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl RefUnwindSafe for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> !RefUnwindSafe for RuntimeApiImpl<Block, C>",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js index cd45ebca..2a276a68 100644 --- a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -3,7 +3,7 @@ "pallet_executive":[["impl<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade> UnwindSafe for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, OnRuntimeUpgrade>
where\n System: UnwindSafe,\n Block: UnwindSafe,\n Context: UnwindSafe,\n UnsignedValidator: UnwindSafe,\n AllPalletsWithSystem: UnwindSafe,\n OnRuntimeUpgrade: UnwindSafe,
",1,["pallet_executive::Executive"]]], "sc_consensus_nakamoto":[["impl !UnwindSafe for Error",1,["sc_consensus_nakamoto::Error"]],["impl !UnwindSafe for Error",1,["sc_consensus_nakamoto::verification::header_verify::Error"]],["impl !UnwindSafe for ImportManyBlocksResult",1,["sc_consensus_nakamoto::import_queue::ImportManyBlocksResult"]],["impl UnwindSafe for BlockVerification",1,["sc_consensus_nakamoto::verification::BlockVerification"]],["impl UnwindSafe for ImportStatus",1,["sc_consensus_nakamoto::block_import::ImportStatus"]],["impl UnwindSafe for BlockImportQueue",1,["sc_consensus_nakamoto::import_queue::BlockImportQueue"]],["impl UnwindSafe for ChainParams",1,["sc_consensus_nakamoto::chain_params::ChainParams"]],["impl UnwindSafe for ImportBlocks",1,["sc_consensus_nakamoto::import_queue::ImportBlocks"]],["impl UnwindSafe for ImportConfig",1,["sc_consensus_nakamoto::block_import::ImportConfig"]],["impl<Block, Client> UnwindSafe for HeaderVerifier<Block, Client>
where\n Client: RefUnwindSafe,\n Block: UnwindSafe,
",1,["sc_consensus_nakamoto::verification::header_verify::HeaderVerifier"]],["impl<Block, Client> UnwindSafe for SubstrateImportQueueVerifier<Block, Client>
where\n Client: RefUnwindSafe,\n Block: UnwindSafe,
",1,["sc_consensus_nakamoto::verifier::SubstrateImportQueueVerifier"]],["impl<Block, Client, BE> !UnwindSafe for BlockVerifier<Block, Client, BE>",1,["sc_consensus_nakamoto::verification::BlockVerifier"]],["impl<Block, Client, BE, BI, TransactionAdapter> !UnwindSafe for BitcoinBlockImporter<Block, Client, BE, BI, TransactionAdapter>",1,["sc_consensus_nakamoto::block_import::BitcoinBlockImporter"]]], "subcoin_crypto":[["impl UnwindSafe for MuHash3072",1,["subcoin_crypto::muhash::MuHash3072"]]], -"subcoin_network":[["impl !UnwindSafe for Error",1,["subcoin_network::Error"]],["impl UnwindSafe for PeerLatency",1,["subcoin_network::sync::PeerLatency"]],["impl UnwindSafe for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl UnwindSafe for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl UnwindSafe for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl UnwindSafe for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl UnwindSafe for Config",1,["subcoin_network::Config"]],["impl UnwindSafe for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl UnwindSafe for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl UnwindSafe for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> !UnwindSafe for Network<Block, Client>",1,["subcoin_network::Network"]]], +"subcoin_network":[["impl !UnwindSafe for Error",1,["subcoin_network::Error"]],["impl UnwindSafe for PeerSyncState",1,["subcoin_network::sync::PeerSyncState"]],["impl UnwindSafe for SendTransactionResult",1,["subcoin_network::network::SendTransactionResult"]],["impl UnwindSafe for SyncStatus",1,["subcoin_network::network::SyncStatus"]],["impl UnwindSafe for SyncStrategy",1,["subcoin_network::SyncStrategy"]],["impl UnwindSafe for Config",1,["subcoin_network::Config"]],["impl UnwindSafe for NetworkHandle",1,["subcoin_network::network::NetworkHandle"]],["impl UnwindSafe for NetworkStatus",1,["subcoin_network::network::NetworkStatus"]],["impl UnwindSafe for PeerSync",1,["subcoin_network::sync::PeerSync"]],["impl<Block, Client> !UnwindSafe for Network<Block, Client>",1,["subcoin_network::Network"]]], "subcoin_primitives":[["impl UnwindSafe for HeaderError",1,["subcoin_primitives::HeaderError"]],["impl UnwindSafe for BlockLocator",1,["subcoin_primitives::BlockLocator"]],["impl UnwindSafe for IndexedBlock",1,["subcoin_primitives::IndexedBlock"]]], "subcoin_rpc":[["impl<Block, Client, TransactionAdapter> UnwindSafe for SubcoinRpc<Block, Client, TransactionAdapter>
where\n Client: RefUnwindSafe,\n Block: UnwindSafe,\n TransactionAdapter: UnwindSafe,
",1,["subcoin_rpc::SubcoinRpc"]]], "subcoin_runtime":[["impl !UnwindSafe for RuntimeOrigin",1,["subcoin_runtime::RuntimeOrigin"]],["impl UnwindSafe for OriginCaller",1,["subcoin_runtime::OriginCaller"]],["impl UnwindSafe for RuntimeCall",1,["subcoin_runtime::RuntimeCall"]],["impl UnwindSafe for RuntimeError",1,["subcoin_runtime::RuntimeError"]],["impl UnwindSafe for RuntimeEvent",1,["subcoin_runtime::RuntimeEvent"]],["impl UnwindSafe for RuntimeTask",1,["subcoin_runtime::RuntimeTask"]],["impl UnwindSafe for BlockWeights",1,["subcoin_runtime::BlockWeights"]],["impl UnwindSafe for PalletInfo",1,["subcoin_runtime::PalletInfo"]],["impl UnwindSafe for Runtime",1,["subcoin_runtime::Runtime"]],["impl UnwindSafe for RuntimeApi",1,["subcoin_runtime::RuntimeApi"]],["impl UnwindSafe for RuntimeGenesisConfig",1,["subcoin_runtime::RuntimeGenesisConfig"]],["impl UnwindSafe for Version",1,["subcoin_runtime::Version"]],["impl<Block, C> !UnwindSafe for RuntimeApiImpl<Block, C>",1,["subcoin_runtime::RuntimeApiImpl"]]], diff --git a/trait.impl/serde/de/trait.Deserialize.js b/trait.impl/serde/de/trait.Deserialize.js index 4572f8fc..4044411f 100644 --- a/trait.impl/serde/de/trait.Deserialize.js +++ b/trait.impl/serde/de/trait.Deserialize.js @@ -1,5 +1,5 @@ (function() {var implementors = { "pallet_bitcoin":[["impl<'de, T> Deserialize<'de> for GenesisConfig<T>"]], -"subcoin_network":[["impl<'de> Deserialize<'de> for PeerLatency"],["impl<'de> Deserialize<'de> for PeerSyncState"],["impl<'de> Deserialize<'de> for SendTransactionResult"],["impl<'de> Deserialize<'de> for SyncStatus"],["impl<'de> Deserialize<'de> for NetworkStatus"],["impl<'de> Deserialize<'de> for PeerSync"]], +"subcoin_network":[["impl<'de> Deserialize<'de> for PeerSyncState"],["impl<'de> Deserialize<'de> for SendTransactionResult"],["impl<'de> Deserialize<'de> for SyncStatus"],["impl<'de> Deserialize<'de> for NetworkStatus"],["impl<'de> Deserialize<'de> for PeerSync"]], "subcoin_runtime":[["impl<'de> Deserialize<'de> for RuntimeGenesisConfig"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/ser/trait.Serialize.js b/trait.impl/serde/ser/trait.Serialize.js index ad252d91..c1e2b839 100644 --- a/trait.impl/serde/ser/trait.Serialize.js +++ b/trait.impl/serde/ser/trait.Serialize.js @@ -1,5 +1,5 @@ (function() {var implementors = { "pallet_bitcoin":[["impl<T> Serialize for GenesisConfig<T>"]], -"subcoin_network":[["impl Serialize for PeerLatency"],["impl Serialize for PeerSyncState"],["impl Serialize for SendTransactionResult"],["impl Serialize for SyncStatus"],["impl Serialize for NetworkStatus"],["impl Serialize for PeerSync"]], +"subcoin_network":[["impl Serialize for PeerSyncState"],["impl Serialize for SendTransactionResult"],["impl Serialize for SyncStatus"],["impl Serialize for NetworkStatus"],["impl Serialize for PeerSync"]], "subcoin_runtime":[["impl Serialize for RuntimeGenesisConfig"]] };if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file