{"id":20109981,"url":"https://github.com/distributed-lab/bpcon","last_synced_at":"2025-09-21T01:32:13.148Z","repository":{"id":250280036,"uuid":"832110872","full_name":"distributed-lab/bpcon","owner":"distributed-lab","description":"Generic Rust library for BPCon (Byzantine Paxos). ","archived":false,"fork":false,"pushed_at":"2024-10-18T17:00:42.000Z","size":104,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-01-11T16:34:47.425Z","etag":null,"topics":["bft","consensus","paxos","rust","stacks"],"latest_commit_sha":null,"homepage":"https://docs.rs/bpcon","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/distributed-lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-22T11:28:02.000Z","updated_at":"2024-12-27T16:11:34.000Z","dependencies_parsed_at":"2024-09-09T16:15:07.739Z","dependency_job_id":"4c4eb0bb-9e2e-4a44-89c9-052dfef2512e","html_url":"https://github.com/distributed-lab/bpcon","commit_stats":null,"previous_names":["distributed-lab/bpcon"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-lab%2Fbpcon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-lab%2Fbpcon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-lab%2Fbpcon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-lab%2Fbpcon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/distributed-lab","download_url":"https://codeload.github.com/distributed-lab/bpcon/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233699714,"owners_count":18716262,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bft","consensus","paxos","rust","stacks"],"created_at":"2024-11-13T18:09:58.589Z","updated_at":"2025-09-21T01:32:07.819Z","avatar_url":"https://github.com/distributed-lab.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Weighted BPCon Rust Library\n\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![Rust CI🌌](https://github.com/distributed-lab/bpcon/actions/workflows/rust.yml/badge.svg)](https://github.com/distributed-lab/bpcon/actions/workflows/rust.yml)\n[![Docs 🌌](https://github.com/distributed-lab/bpcon/actions/workflows/docs.yml/badge.svg)](https://github.com/distributed-lab/bpcon/actions/workflows/docs.yml)\n\n\u003e This is a rust library implementing weighted BPCon consensus.\n\n## Documentation\n\nLibrary is documented with `rustdoc`.\nCompiled production documentation for `main` branch is available at https://docs.rs/bpcon.\nFor other branches, development documentation is published to [GitBook](https://distributed-lab.github.io/bpcon/).\n\n## Usage\n\n### Add dependency in your `Cargo.toml`\n\n```toml\n[dependencies]\nbpcon = \"0.1.0\"\n```\n\n### Implement [Value](https://distributed-lab.github.io/bpcon/bpcon/value/trait.Value.html) trait\n\nThis is a core trait, which defines what type are you selecting in your consensus.\nIt may be the next block in blockchain, or leader for some operation, or anything else you need.\n\nBelow is a simple example, where we will operate on selection for `u64` type.\nUsing it you may interpret `ID` for leader of distributed operation, for instance.\n\n```rust\n...\nuse bpcon::value::Value;\n\n#[derive(Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Debug, Hash)]\npub(crate) struct MyValue(u64);\n\nimpl Value for MyValue {}\n```\n\n### Implement [ValueSelector](https://distributed-lab.github.io/bpcon/bpcon/value/trait.ValueSelector.html) trait\n\n`BPCon` allows you to define specific conditions how proposer (leader) will select value\nand how other members will verify its selection.\n\nHere is a simple example:\n\n```rust\n...\nuse bpcon::value::ValueSelector;\n\n#[derive(Clone)]\npub struct MyValueSelector;\n\nimpl ValueSelector\u003cMyValue\u003e for MyValueSelector {\n    /// Verifies if the given value `v` has been correctly selected according to the protocol rules.\n    ///\n    /// In this basic implementation, we'll consider a value as \"correctly selected\" if it matches\n    /// the majority of the values in the provided `HashMap`.\n    fn verify(\u0026self, v: \u0026MyValue, m: \u0026HashMap\u003cu64, Option\u003cMyValue\u003e\u003e) -\u003e bool {\n        // Count how many times the value `v` appears in the `HashMap`\n        let count = m.values().filter(|\u0026val| val.as_ref() == Some(v)).count();\n\n        // For simplicity, consider the value verified if it appears in more than half of the entries\n        count \u003e m.len() / 2\n    }\n\n    /// Selects a value based on the provided `HashMap` of party votes.\n    ///\n    /// This implementation selects the value that appears most frequently in the `HashMap`.\n    /// If there is a tie, it selects the smallest value (as per the natural ordering of `u64`).\n    fn select(\u0026self, m: \u0026HashMap\u003cu64, Option\u003cMyValue\u003e\u003e) -\u003e MyValue {\n        let mut frequency_map = HashMap::new();\n\n        // Count the frequency of each value in the `HashMap`\n        for value in m.values().flatten() {\n            *frequency_map.entry(value).or_insert(0) += 1;\n        }\n\n        // Find the value with the highest frequency. In case of a tie, select the smallest value.\n        frequency_map\n            .into_iter()\n            .max_by_key(|(value, count)| (*count, value.0))\n            .map(|(value, _)| value.clone())\n            .expect(\"No valid value found\")\n    }\n}\n```\n\n### Decide on a [LeaderElector](https://distributed-lab.github.io/bpcon/bpcon/leader/trait.LeaderElector.html)\n\n`LeaderElector` trait allows you to define specific conditions, how to select leader for consensus.\n\n**NOTE: it is important to provide deterministic mechanism,\nbecause each participant will compute leader for itself,\nand in case it is not deterministic, state divergence occurs.**\n\nWe also provide ready-to-use\n[DefaultLeaderElector](https://distributed-lab.github.io/bpcon/bpcon/leader/struct.DefaultLeaderElector.html)\nwhich is using weighted randomization.\n\n### Configure your ballot\n\nAs a next step, you need to decide on parameters for your ballot:\n\n1. Amount of parties and their weight.\n2. Threshold weight.\n3. Time bounds.\n\nExample:\n\n```rust\nuse bpcon::config::BPConConfig;\n\nlet cfg = BPConConfig::with_default_timeouts(vec![1, 1, 1, 1, 1, 1], 4);\n```\n\nFeel free to explore [config.rs](https://distributed-lab.github.io/bpcon/bpcon/config/struct.BPConConfig.html)\nfor more information.\n\n### Create parties\n\nHaving `BPConConfig`, `ValueSelector` and `LeaderElector` defined, instantiate your parties.\nCheck out [new](https://distributed-lab.github.io/bpcon/bpcon/party/struct.Party.html#method.new)\nmethod on a `Party` struct.\n\n### Launch ballot on parties and handle messages\n\nEach party interfaces communication with external system via channels.\nIn a way, you shall propagate outgoing messages to other parties like:\n\n1. Listen for outgoing message using `msg_out_receiver`.\n2. Forward it to other parties using `msg_in_sender`.\n\nWe welcome you to check our [integration tests](./tests) for examples.\n\n## Security Considerations 🔐\n\n### Categories of parties\n\nIn real world applications, we may categorize parties by their behavior to following:\n\n1. Good - party sends messages to other participants based on following events,\n   and correctly receives and processes messages from other parties.\n\n2. Faulty - party has troubles receiving/sending messages.\n   These are simply mitigated by the weighed threshold and redundancy of consensus participants.\n\n3. Malicious - party launches DDoS attack using unbounded sending of messages -\n   to deal with this, we introduce rate-limiting mechanism in accepting messages inside the `Party`,\n   however it is also ❗️ required by integrating 'external' system ❗️, which handles `P2P`, to attest to this, because otherwise receiving channel may get flooded by malicious messages and block messages from other parties.\n   Another way to cause trouble is by sending invalid messages. For this, each party has\n   a set of checks for certain fields like current ballot number, status, etc.\n   Additionally, if the state transition caused by incoming message errored, it does not impact the party in either way.\n\n### Note on the leader 👑\n\nIf the `leader` of the ballot is faulty or malicious, the ballot deterministically fails and needs to be relaunched.\n\n### Note on the communication discrepancies 🔇\n\nEach party has a certain period in which it may accept particular messages for a certain stage\n(example: having passed 1a stage, it is open for accepting only 1b messages for 2 seconds).\nThese periods are configurable using `BPConConfig`, meaning you can program certain ranges\nto allow slow parties to catch up, while others are waiting, before transiting to the next stage.\n\nIn addition it is possible to schedule parties to launch at specific absolute time.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributed-lab%2Fbpcon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdistributed-lab%2Fbpcon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributed-lab%2Fbpcon/lists"}