{"id":29021478,"url":"https://github.com/freenet/freenet-scaffold","last_synced_at":"2025-06-26T02:06:11.597Z","repository":{"id":288615355,"uuid":"968686800","full_name":"freenet/freenet-scaffold","owner":"freenet","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-19T18:20:05.000Z","size":25,"stargazers_count":1,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-22T20:41:55.277Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/freenet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2025-04-18T14:42:25.000Z","updated_at":"2025-05-20T19:23:47.000Z","dependencies_parsed_at":"2025-04-19T04:13:08.921Z","dependency_job_id":"3762f0e0-b0ff-45a8-94cc-4c7a0af23120","html_url":"https://github.com/freenet/freenet-scaffold","commit_stats":null,"previous_names":["freenet/freenet-scaffold"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/freenet/freenet-scaffold","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenet%2Ffreenet-scaffold","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenet%2Ffreenet-scaffold/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenet%2Ffreenet-scaffold/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenet%2Ffreenet-scaffold/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freenet","download_url":"https://codeload.github.com/freenet/freenet-scaffold/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenet%2Ffreenet-scaffold/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261984647,"owners_count":23240303,"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":[],"created_at":"2025-06-26T02:06:10.795Z","updated_at":"2025-06-26T02:06:11.579Z","avatar_url":"https://github.com/freenet.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Freenet Scaffold\n\n`freenet-scaffold` is a Rust utility crate that simplifies the development of Freenet contracts by\nproviding tools to implement efficient, mergeable state synchronization.\n\n## Overview\n\nIn decentralized systems like Freenet, achieving consistency across nodes without heavy coordination\nis challenging. Traditional methods often rely on consensus algorithms, which can be\nresource-intensive and less scalable. Freenet addresses this by using a summary-delta\nsynchronization approach, where each node summarizes its state and exchanges deltas—minimal changes\nneeded to update another node's state. This method reduces bandwidth usage and allows for efficient,\ndeterministic merging of states across the network.\n\nThe `freenet-scaffold` crate provides the `ComposableState` trait and associated utilities to\nimplement this approach in Rust. It enables developers to define how their data structures can be\nsummarized, how deltas are computed, and how to apply these deltas to achieve eventual consistency.\n\n## Getting Started\n\n### Installation\n\nAdd the following to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfreenet-scaffold = \"0.2\"\nfreenet-scaffold-macro = \"0.2\"\n```\n\nThe `freenet-scaffold-macro` crate provides the `#[composable]` procedural macro, which derives\nimplementations of the `ComposableState` trait for structs whose fields also implement\n`ComposableState`. This macro re-exports everything from `freenet-scaffold`, so importing\n`freenet-scaffold-macro` is typically sufficient.\n\n### Example\n\nHere's a minimal example demonstrating how to use `freenet-scaffold` and `freenet-scaffold-macro`:\n\n```rust\nuse freenet_scaffold::{ComposableState, util::FastHash};\nuse freenet_scaffold_macro::composable;\nuse serde::{Serialize, Deserialize};\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct Params;\n\n#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]\npub struct ContractualI32(pub i32);\n\nimpl ComposableState for ContractualI32 {\n    type ParentState = Test;\n    type Summary = i32;\n    type Delta = i32;\n    type Parameters = Params;\n\n    fn verify(\u0026self, _: \u0026Self::ParentState, _: \u0026Self::Parameters) -\u003e Result\u003c(), String\u003e { Ok(()) }\n    fn summarize(\u0026self, _: \u0026Self::ParentState, _: \u0026Self::Parameters) -\u003e Self::Summary { self.0 }\n    fn delta(\u0026self, _: \u0026Self::ParentState, _: \u0026Self::Parameters, old: \u0026Self::Summary) -\u003e Option\u003cSelf::Delta\u003e {\n        let diff = self.0 - *old; if diff == 0 { None } else { Some(diff) }\n    }\n    fn apply_delta(\u0026mut self, _: \u0026Self::ParentState, _: \u0026Self::Parameters, delta: \u0026Option\u003cSelf::Delta\u003e) -\u003e Result\u003c(), String\u003e {\n        if let Some(d) = delta { self.0 += *d; } Ok(())\n    }\n}\n\n#[composable]\n#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]\npub struct Test {\n    number: ContractualI32,\n    // Add other fields implementing ComposableState\n}\n```\n\nThe `#[composable]` macro automatically generates the necessary summary and delta structures, as\nwell as the `ComposableState` implementation for the `Test` struct.\n\n## Best Practices\n\n- **Field Order Matters**: When using `#[composable]`, ensure that fields are ordered such that any\n  field depending on another appears after it. This is important for cases where one field's\n  `apply_delta` relies on another field's state.\n\n## License\n\nThis project is licensed under the **GNU Lesser General Public License v2.1** (LGPL-2.1-only).\n\n## Contributing\n\nPull requests are welcome.\n\n---\n\nFor a deeper understanding of the summary-delta synchronization approach and its advantages in\ndecentralized systems, refer to the article:\n[Understanding Freenet's Delta-Sync](https://freenet.org/news/summary-delta-sync/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreenet%2Ffreenet-scaffold","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreenet%2Ffreenet-scaffold","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreenet%2Ffreenet-scaffold/lists"}