mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-10 14:00:33 +00:00
1 line
14 KiB
JavaScript
1 line
14 KiB
JavaScript
(window.webpackJsonp=window.webpackJsonp||[]).push([[134],{704:function(e,t,n){"use strict";n.r(t);var a=n(1),o=Object(a.a)({},(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[n("h1",{attrs:{id:"adr-073-adopt-libp2p"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#adr-073-adopt-libp2p"}},[e._v("#")]),e._v(" ADR 073: Adopt LibP2P")]),e._v(" "),n("h2",{attrs:{id:"changelog"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changelog"}},[e._v("#")]),e._v(" Changelog")]),e._v(" "),n("ul",[n("li",[e._v("2021-11-02: Initial Draft (@tychoish)")])]),e._v(" "),n("h2",{attrs:{id:"status"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#status"}},[e._v("#")]),e._v(" Status")]),e._v(" "),n("p",[e._v("Proposed.")]),e._v(" "),n("h2",{attrs:{id:"context"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#context"}},[e._v("#")]),e._v(" Context")]),e._v(" "),n("p",[e._v("As part of the 0.35 development cycle, the Tendermint team completed\nthe first phase of the work described in ADRs 61 and 62, which included a\nlarge scale refactoring of the reactors and the p2p message\nrouting. This replaced the switch and many of the other legacy\ncomponents without breaking protocol or network-level\ninteroperability and left the legacy connection/socket handling code.")]),e._v(" "),n("p",[e._v("Following the release, the team has reexamined the state of the code\nand the design, as well as Tendermint's requirements. The notes\nfrom that process are available in the "),n("a",{attrs:{href:"../rfc/rfc-000-p2p-roadmap.rst"}},[e._v("P2P Roadmap\nRFC")]),e._v(".")]),e._v(" "),n("p",[e._v('This ADR supersedes the decisions made in ADRs 60 and 61, but\nbuilds on the completed portions of this work. Previously, the\nboundaries of peer management, message handling, and the higher level\nbusiness logic (e.g., "the reactors") were intermingled, and core\nelements of the p2p system were responsible for the orchestration of\nhigher-level business logic. Refactoring the legacy components\nmade it more obvious that this entanglement of responsibilities\nhad outsized influence on the entire implementation, making\nit difficult to iterate within the current abstractions.\nIt would not be viable to maintain interoperability with legacy\nsystems while also achieving many of our broader objectives.')]),e._v(" "),n("p",[e._v("LibP2P is a thoroughly-specified implementation of a peer-to-peer\nnetworking stack, designed specifically for systems such as\nours. Adopting LibP2P as the basis of Tendermint will allow the\nTendermint team to focus more of their time on other differentiating\naspects of the system, and make it possible for the ecosystem as a\nwhole to take advantage of tooling and efforts of the LibP2P\nplatform.")]),e._v(" "),n("h2",{attrs:{id:"alternative-approaches"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#alternative-approaches"}},[e._v("#")]),e._v(" Alternative Approaches")]),e._v(" "),n("p",[e._v("As discussed in the "),n("a",{attrs:{href:"../rfc/rfc-000-p2p-roadmap.rst"}},[e._v("P2P Roadmap RFC")]),e._v(", the primary alternative would be to\ncontinue development of Tendermint's home-grown peer-to-peer\nlayer. While that would give the Tendermint team maximal control\nover the peer system, the current design is unexceptional on its\nown merits, and the prospective maintenance burden for this system\nexceeds our tolerances for the medium term.")]),e._v(" "),n("p",[e._v("Tendermint can and should differentiate itself not on the basis of\nits networking implementation or peer management tools, but providing\na consistent operator experience, a battle-tested consensus algorithm,\nand an ergonomic user experience.")]),e._v(" "),n("h2",{attrs:{id:"decision"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#decision"}},[e._v("#")]),e._v(" Decision")]),e._v(" "),n("p",[e._v("Tendermint will adopt libp2p during the 0.37 development cycle,\nreplacing the bespoke Tendermint P2P stack. This will remove the\n"),n("code",[e._v("Endpoint")]),e._v(", "),n("code",[e._v("Transport")]),e._v(", "),n("code",[e._v("Connection")]),e._v(", and "),n("code",[e._v("PeerManager")]),e._v(" abstractions\nand leave the reactors, "),n("code",[e._v("p2p.Router")]),e._v(" and "),n("code",[e._v("p2p.Channel")]),e._v("\nabstractions.")]),e._v(" "),n("p",[e._v("LibP2P may obviate the need for a dedicated peer exchange (PEX)\nreactor, which would also in turn obviate the need for a dedicated\nseed mode. If this is the case, then all of this functionality would\nbe removed.")]),e._v(" "),n("p",[e._v("If it turns out (based on the advice of Protocol Labs) that it makes\nsense to maintain separate pubsub or gossipsub topics\nper-message-type, then the "),n("code",[e._v("Router")]),e._v(" abstraction could also\nbe entirely subsumed.")]),e._v(" "),n("h2",{attrs:{id:"detailed-design"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#detailed-design"}},[e._v("#")]),e._v(" Detailed Design")]),e._v(" "),n("h3",{attrs:{id:"implementation-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#implementation-changes"}},[e._v("#")]),e._v(" Implementation Changes")]),e._v(" "),n("p",[e._v("The seams in the P2P implementation between the higher level\nconstructs (reactors), the routing layer ("),n("code",[e._v("Router")]),e._v(") and the lower\nlevel connection and peer management code make this operation\nrelatively straightforward to implement. A key\ngoal in this design is to minimize the impact on the reactors\n(potentially entirely,) and completely remove the lower level\ncomponents (e.g., "),n("code",[e._v("Transport")]),e._v(", "),n("code",[e._v("Connection")]),e._v(" and "),n("code",[e._v("PeerManager")]),e._v(") using the\nseparation afforded by the "),n("code",[e._v("Router")]),e._v(" layer. The current state of the\ncode makes these changes relatively surgical, and limited to a small\nnumber of methods:")]),e._v(" "),n("ul",[n("li",[n("p",[n("code",[e._v("p2p.Router.OpenChannel")]),e._v(" will still return a "),n("code",[e._v("Channel")]),e._v(" structure\nwhich will continue to serve as a pipe between the reactors and the\n"),n("code",[e._v("Router")]),e._v(". The implementation will no longer need the queue\nimplementation, and will instead start goroutines that\nare responsible for routing the messages from the channel to libp2p\nfundamentals, replacing the current "),n("code",[e._v("p2p.Router.routeChannel")]),e._v(".")])]),e._v(" "),n("li",[n("p",[e._v("The current "),n("code",[e._v("p2p.Router.dialPeers")]),e._v(" and "),n("code",[e._v("p2p.Router.acceptPeers")]),e._v(",\nare responsible for establishing outbound and inbound connections,\nrespectively. These methods will be removed, along with\n"),n("code",[e._v("p2p.Router.openConnection")]),e._v(", and the libp2p connection manager will\nbe responsible for maintaining network connectivity.")])]),e._v(" "),n("li",[n("p",[e._v("The "),n("code",[e._v("p2p.Channel")]),e._v(" interface will change to replace Go\nchannels with a more functional interface for sending messages.\nNew methods on this object will take contexts to support safe\ncancellation, and return errors, and will block rather than\nrunning asynchronously. The "),n("code",[e._v("Out")]),e._v(" channel through which\nreactors send messages to Peers, will be replaced by a "),n("code",[e._v("Send")]),e._v("\nmethod, and the Error channel will be replaced by an "),n("code",[e._v("Error")]),e._v("\nmethod.")])]),e._v(" "),n("li",[n("p",[e._v("Reactors will be passed an interface that will allow them to\naccess Peer information from libp2p. This will supplant the\n"),n("code",[e._v("p2p.PeerUpdates")]),e._v(" subscription.")])]),e._v(" "),n("li",[n("p",[e._v("Add some kind of heartbeat message at the application level\n(e.g. with a reactor,) potentially connected to libp2p's DHT to be\nused by reactors for service discovery, message targeting, or other\nfeatures.")])]),e._v(" "),n("li",[n("p",[e._v("Replace the existing/legacy handshake protocol with "),n("a",{attrs:{href:"http://www.noiseprotocol.org/noise.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Noise"),n("OutboundLink")],1),e._v(".")])])]),e._v(" "),n("p",[e._v("This project will initially use the TCP-based transport protocols within\nlibp2p. QUIC is also available as an option that we may implement later.\nWe will not support mixed networks in the initial release, but will\nrevisit that possibility later if there is a demonstrated need.")]),e._v(" "),n("h3",{attrs:{id:"upgrade-and-compatibility"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#upgrade-and-compatibility"}},[e._v("#")]),e._v(" Upgrade and Compatibility")]),e._v(" "),n("p",[e._v("Because the routers and all current P2P libraries are "),n("code",[e._v("internal")]),e._v("\npackages and not part of the public API, the only changes to the public\nAPI surface area of Tendermint will be different configuration\nfile options, replacing the current P2P options with options relevant\nto libp2p.")]),e._v(" "),n("p",[e._v("However, it will not be possible to run a network with both networking\nstacks active at once, so the upgrade to the version of Tendermint\nwill need to be coordinated between all nodes of the network. This is\nconsistent with the expectations around upgrades for Tendermint moving\nforward, and will help manage both the complexity of the project and\nthe implementation timeline.")]),e._v(" "),n("h2",{attrs:{id:"open-questions"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#open-questions"}},[e._v("#")]),e._v(" Open Questions")]),e._v(" "),n("ul",[n("li",[n("p",[e._v("What is the role of Protocol Labs in the implementation of libp2p in\ntendermint, both during the initial implementation and on an ongoing\nbasis thereafter?")])]),e._v(" "),n("li",[n("p",[e._v("Should all P2P traffic for a given node be pushed to a single topic,\nso that a topic maps to a specific ChainID, or should\neach reactor (or type of message) have its own topic? How many\ntopics can a libp2p network support? Is there testing that validates\nthe capabilities?")])]),e._v(" "),n("li",[n("p",[e._v("Tendermint presently provides a very coarse QoS-like functionality\nusing priorities based on message-type.\nThis intuitively/theoretically ensures that evidence and consensus\nmessages don't get starved by blocksync/statesync messages. It's\nunclear if we can or should attempt to replicate this with libp2p.")])]),e._v(" "),n("li",[n("p",[e._v("What kind of QoS functionality does libp2p provide and what kind of\nmetrics does libp2p provide about it's QoS functionality?")])]),e._v(" "),n("li",[n("p",[e._v("Is it possible to store additional (and potentially arbitrary)\ninformation into the DHT as part of the heartbeats between nodes,\nsuch as the latest height, and then access that in the\nreactors. How frequently can the DHT be updated?")])]),e._v(" "),n("li",[n("p",[e._v("Does it make sense to have reactors continue to consume inbound\nmessages from a Channel ("),n("code",[e._v("In")]),e._v(") or is there another interface or\npattern that we should consider?")]),e._v(" "),n("ul",[n("li",[e._v("We should avoid exposing Go channels when possible, and likely\nsome kind of alternate iterator likely makes sense for processing\nmessages within the reactors.")])])]),e._v(" "),n("li",[n("p",[e._v("What are the security and protocol implications of tracking\ninformation from peer heartbeats and exposing that to reactors?")])]),e._v(" "),n("li",[n("p",[e._v("How much (or how little) configuration can Tendermint provide for\nlibp2p, particularly on the first release?")]),e._v(" "),n("ul",[n("li",[e._v("In general, we should not support byo-functionality for libp2p\ncomponents within Tendermint, and reduce the configuration surface\narea, as much as possible.")])])]),e._v(" "),n("li",[n("p",[e._v("What are the best ways to provide request/response semantics for\nreactors on top of libp2p? Will it be possible to add\nrequest/response semantics in a future release or is there\nanticipatory work that needs to be done as part of the initial\nrelease?")])])]),e._v(" "),n("h2",{attrs:{id:"consequences"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#consequences"}},[e._v("#")]),e._v(" Consequences")]),e._v(" "),n("h3",{attrs:{id:"positive"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#positive"}},[e._v("#")]),e._v(" Positive")]),e._v(" "),n("ul",[n("li",[n("p",[e._v("Reduce the maintenance burden for the Tendermint Core team by\nremoving a large swath of legacy code that has proven to be\ndifficult to modify safely.")])]),e._v(" "),n("li",[n("p",[e._v("Remove the responsibility for maintaining and developing the entire\npeer management system (p2p) and stack.")])]),e._v(" "),n("li",[n("p",[e._v("Provide users with a more stable peer and networking system,\nTendermint can improve operator experience and network stability.")])])]),e._v(" "),n("h3",{attrs:{id:"negative"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#negative"}},[e._v("#")]),e._v(" Negative")]),e._v(" "),n("ul",[n("li",[n("p",[e._v("By deferring to library implementations for peer management and\nnetworking, Tendermint loses some flexibility for innovating at the\npeer and networking level. However, Tendermint should be innovating\nprimarily at the consensus layer, and libp2p does not preclude\noptimization or development in the peer layer.")])]),e._v(" "),n("li",[n("p",[e._v("Libp2p is a large dependency and Tendermint would become dependent\nupon Protocol Labs' release cycle and prioritization for bug\nfixes. If this proves onerous, it's possible to maintain a vendor\nfork of relevant components as needed.")])])]),e._v(" "),n("h3",{attrs:{id:"neutral"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#neutral"}},[e._v("#")]),e._v(" Neutral")]),e._v(" "),n("ul",[n("li",[e._v("N/A")])]),e._v(" "),n("h2",{attrs:{id:"references"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[e._v("#")]),e._v(" References")]),e._v(" "),n("ul",[n("li",[n("RouterLink",{attrs:{to:"/architecture/adr-061-p2p-refactor-scope.html"}},[e._v("ADR 61: P2P Refactor Scope")])],1),e._v(" "),n("li",[n("RouterLink",{attrs:{to:"/architecture/adr-062-p2p-architecture.html"}},[e._v("ADR 62: P2P Architecture")])],1),e._v(" "),n("li",[n("a",{attrs:{href:"../rfc/rfc-000-p2p-roadmap.rst"}},[e._v("P2P Roadmap RFC")])])])])}),[],!1,null,null,null);t.default=o.exports}}]); |