Document not found (404)
+This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..05d10b9ce --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: freenet, sanity # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..51d4fa994 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 9999 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 000000000..0e47885cb --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,16 @@ +name: Security audit +on: + push: + paths: + - "**/Cargo.toml" + - "**/Cargo.lock" + schedule: + - cron: "0 0 * * *" +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..430f9bcf8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,99 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + name: Test + + runs-on: ubuntu-latest + strategy: + matrix: + args: + [ + "--no-default-features", + "--all-features", + "--benches --all-features", + ] + env: + LOCUTUS_LOG: error + CARGO_TARGET_DIR: ${{ github.workspace }}/target" + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.10.0 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v3 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: "true" + default: "true" + + - uses: Swatinem/rust-cache@v1 + + - name: Build + run: cargo build --locked + + - name: Add wasm32-unknown-unknown + run: rustup target add wasm32-unknown-unknown + + - name: Install stdlib packages + working-directory: apps/stdlib + run: npm install + + - name: Test + run: cargo test --workspace ${{ matrix.args }} + + clippy_check: + name: Clippy + + runs-on: ubuntu-latest + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.10.0 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v3 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + components: clippy + override: "true" + default: "true" + + - uses: Swatinem/rust-cache@v1 + + - name: Clippy + run: cargo clippy -- -D warnings + + fmt_check: + name: Fmt + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + components: rustfmt + override: "true" + default: "true" + + - name: Check code formatting + run: cargo fmt -- --check diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..5938cb914 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,34 @@ +name: Deploy Documentation + +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Install mdbook + run: | + mkdir mdbook + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook + echo `pwd`/mdbook >> $GITHUB_PATH + - name: Deploy GitHub Pages + run: | + cd docs + mdbook build + git worktree add gh-pages + git config user.name "Deploy from CI" + git config user.email "" + cd gh-pages + # Delete the ref to avoid keeping history. + #### Disabled following line to avoid screwing up custom domain + #### git update-ref -d refs/heads/gh-pages + rm -rf * + mv ../book/* . + git add . + git commit -m "Deploy $GITHUB_SHA to gh-pages" + git push --force --set-upstream origin gh-pages diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..f17311098 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/404.html b/404.html new file mode 100644 index 000000000..8305bbf70 --- /dev/null +++ b/404.html @@ -0,0 +1,220 @@ + + +
+ + +This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +Freenet's request routing mechanism plays a crucial role in the efficiency of +the network.
+It is responsible for deciding which peer to route a request to when attempting +to read, create, or modify a contract's state. The mechanism is designed to +select the peer that can complete the request the fastest, which may not always +be the peer closest to the contract's location - the traditional approach for +routing in a small-world network, known as greedy +routing.
+Freenet uses isotonic regression, a method +for estimating a monotonically increasing or decreasing function given a set of +data, to predict the response time from a peer based on its ring distance from +the target location of the request.
+This estimation is then adjusted by the average difference between the isotonic +regression estimate and the actual response time from previous interactions with +the peer. This process enables a form of adaptive routing that selects the peer +with the lowest estimated response time.
+When a new +Router +is created, it's initialized with a history of routing events. These events are +processed to generate the initial state of the isotonic estimators. For example, +failure outcomes and success durations are computed for each event in the +history and used to initialize the respective estimators. The average transfer +size is also computed from the history.
+The Router can add new events to its history, updating its estimators in the +process. When a successful routing event occurs, the Router updates its response +start time estimator, failure estimator, and transfer rate estimator based on +the details of the event. If a failure occurs, only the failure estimator is +updated.
+To select a peer for routing a request, the Router first checks whether it has +sufficient historical data. If not, it selects the peer with the minimum +distance to the contract location. If it does have sufficient data, it predicts +the outcome of routing the request to each available peer and selects the one +with the best predicted outcome.
+To predict the outcome of routing a request to a specific peer, the Router uses +its isotonic estimators to predict the time to the start of the response, the +chance of failure, and the transfer rate. These predictions are used to compute +an expected total time for the request, with the cost of a failure being assumed +as a multiple of the cost of success. The peer with the lowest expected total +time is selected for routing the request.
+ +Freenet is structured as a decentralized peer-to-peer network, based on the idea of +a small-world network. This +network topology is scalable and efficient, allowing contract state to be found +quickly and without any reliance on a central authority.
+ +In Freenet, a "peer" is any computer running the Freenet +Core software. The peers are organized +in a ring-like structure, with each peer assigned a specific numerical value +between 0.0 and 1.0, indicating its location in the network's topology. This +location is derived from the peer's public key.
+Every Freenet peer, also referred to as a node, forms two-way connections with a +set of other peers, termed "neighbors." These connections utilize the User +Datagram Protocol (UDP) and can do Frewall hole punching when necessary. Peers manage their resource usage — +bandwidth, memory, CPU, and storage — based on limits set by the user.
+Peers keep track of their neighbor's performance and learn to prefer faster +connections over time.
+Peers can also identify bad behavior by other peers like excess resource usage and +will disconnect from them.
+ +Note: This document is a work in progress and is subject to change, it is currently out-of-sync +with the codebase and should be updated to reflect the current state of the codebase once it has +stabilized.
+The Freenet Transport Protocol (FrTP) is a UDP-based system designed to ensure reliable and encrypted +message transmission. This document outlines the key elements of FrTP, including connection +establishment, message handling, and rate limiting.
+This describes how to establish one side of a two-way connection, allowing Bob to send messages +to Alice. The process is symmetric in the other direction.
+Bob_public_key
: Bob's RSA public key.Bob_private_key
: Bob's RSA private key.Alice_inbound_symmetric_key
: AES128GCM symmetric key generated by Alice, used for decrypting
+inbound messages from Bob.hello_message(A->B)
: Message sent from Alice to Bob, containing Alice_inbound_symmetric_key
+and a u16 protocol version number, encrypted using B_public_key
.hello_ack(B->A)
: Message sent from Bob to Alice acknowledging hello_message(A->B)
,
+encrypted using Alice_inbound_symmetric_key
.Key Generation: Alice generates a random AES128GCM symmetric key,
+called Alice_inbound_symmetric_key
.
Outbound Hello Message: Alice encrypts Alice_inbound_symmetric_key
with Bob_public_key
and
+a u16 protocol version number with Peer B's public key, to create hello_message(A->B)
.
Sending Outbound Hello: Alice repeatedly sends hello_message(A->B)
every 200ms until
+a hello_ack(B->A)
from Bob is received or a 5-second timeout occurs, indicating connection
+failure.
Receiving Inbound Hello: Bob receives hello_message(A->B)
and decrypts it using
+Bob_private_key
. If the protocol version is not supported, then Bob sends a hello_ack(B->A)
+with an error code and terminates the connection.
Hello Acknowledgement: Upon receiving hello_ack(B->A)
, Alice stops sending hello_message(A->B)
+and the inbound side of the connection is established.
Unexpected Hello Messages: If Bob receives a hello_message(A->B)
from Alice after
+it has already sent a hello_ack(B->A)
, then it should resend the hello_ack(B->A)
and
+otherwise ignore the message (this may occur if the initial hello_ack(B->A)
is lost).
Gateway_public_key
: Gateway's RSA public key.Gateway_private_key
: Gateway's RSA private key.Alice_bidirectional_symmetric_key
: AES128GCM symmetric key generated by Alice, used for encrypting
+and decrypting messages to/from Gateway.Key Generation: Alice generates a random AES128GCM symmetric key,
+called Alice_bidrectional_symmetric_key
.
Outbound Hello Message: Alice encrypts Alice_bidrectional_symmetric_key
with Gateway_public_key
and
+a u16 protocol version number with Gateway's public key, to create hello_message(A->G)
.
Sending Outbound Hello: Alice repeatedly sends hello_message(A->B)
every 200ms until
+a hello_ack(G->A)
from Gateway is received or a 5-second timeout occurs, indicating connection
+failure.
Receiving Inbound Hello: Gateway receives hello_message(A->G)
and decrypts it using
+Gateway_private_key
. If the protocol version is not supported, then Gateway sends a hello_ack(G->A)
+with an error code and terminates the connection, otherwise it sends a hello_ack(G->A)
to Alice.
Hello Acknowledgement: Upon receiving hello_ack(G->A)
, Alice stops sending hello_message(A->G)
,
+and the the connection is established, Alice should use Alice_bidirectional_symmetric_key
for
+both encryption and decryption of packets sent to and received from Gateway.
To maintain an open connection, keep_alive
messages are exchanged every 30 seconds. A connection
+is terminated if a peer fails to receive any message within 120 seconds.
+#![allow(unused)] +fn main() { +pub(super) struct SymmetricMessage { + pub packet_id: PacketId, + pub confirm_receipt: Vec<PacketId>, + pub payload: SymmetricMessagePayload, +} + +pub(super) enum SymmetricMessagePayload { + AckConnection { + // if we successfully connected to a remote we attempt to connect to initially + // then we return our TransportPublicKey so they can enroute other peers to us + result: Result<(), Cow<'static, str>>, + }, + GatewayConnection { + // a gateway acknowledges a connection and returns the private key to use + // for communication + key: [u8; 16], + }, + ShortMessage { + payload: MessagePayload, + }, + StreamFragment { + stream_id: StreamId, + total_length_bytes: u64, // we shouldn't allow messages larger than u32, that's already crazy big + fragment_number: u32, + payload: MessagePayload, + }, + NoOp, +} + +pub enum HelloError { + UnsupportedProtocolVersion { + min_supported: u16, + max_supported: u16, + your_version: u16 + }, +} +}
message_id
. Duplicates trigger
+an immediate NoOperation
message with a reconfirmation in confirm_receipt
.MESSAGE_CONFIRMATION_TIMEOUT
).MAX_CONFIRMATION_DELAY
) to enable
+batch confirmation.BANDWIDTH_MEASUREMENT_WINDOW
).
+Exceeding limits
+triggers a 10ms sleep (BANDWIDTH_CONTROL_SLEEP_DURATION
), with periodic reassessment.Consider:
+ +The Freenet Transport Protocol provides a robust framework for secure and efficient data +transmission. Its design considers NAT challenges, message integrity, and bandwidth management, +ensuring reliable communication in various network conditions.
+ +Freenet is essentially a global decentralized key-value store where keys are +WebAssembly code called Contracts. Contracts are stored in the network, +along with their data or "state". The contract controls what state is permitted +and how it can be modified, and also how to efficiently synchronize state +between peers.
+A contract's state is just a block of bytes, and can be anything from a simple +number to a complex data structure. The contract's code defines the state's +formatting. Even the serialization format is up to the contract, so it can be +anything from JSON to Bincode, or a custom binary format.
+Network users can read a contract's state and subscribe to receive immediate +updates if the state is modified.
+Contracts play a similar role in Freenet to databases and real-time +publish-subscribe mechanisms in traditional online services, while being +entirely decentralized, secure, and scalable.
+Contracts need to provide a mechanism to merge any two valid states, creating a +new state that integrates both. This process ensures the eventual consistency of +contract states in Freenet, a concept similar to Conflict-free Replicated Data +Types.
+As a very simple example, if the contract's state is a single number, then the +contract could define the merging of two states as the maximum of the two numbers.
+In mathematical terms, a contract defines a commutative +monoid on the contract's +state - but you can ignore this if you're not a mathematician.
+Naively we could transfer the entire state between peers, but this would be +inefficient for larger states. Instead, Freenet transmits only the +difference between states.
+To do this a contract implements three functions:
+summarize_state
- Returns a concise summary of the contract's
+state.
get_state_delta
- Compares the contract's state against the summary of
+another state and returns the difference between the two, the "delta".
update_state
- Applies a delta to the contract's state, updating it to
+bring it in sync with the other peer's contract state.
Contracts can implement these functions however they wish depending on the +type of data their state contains.
+PeerA and PeerB need to synchronize their states. The algorithm for efficient +state synchronization consists of the following steps:
+Summarize State by Initiator: PeerA compiles a concise summary of its
+current state using the summarize_state
function.
Compare State at Receiver: PeerB uses get_state_delta
to compare the
+summary against its own state.
Send Delta: If the states are different, PeerB calculates the delta and +sends it to PeerA.
+Apply Delta: PeerA applies this received delta to its state using
+update_state
.
Reverse Synchronization: This process is repeated in the opposite direction.
+This approach allows peers to synchronize state over the network while minimizing +data transfer.
+Consider a public blog contract. The state of this contract would be the blog's +content, including blog posts. The contract's code requires that new +posts can only be added if they are signed by the blog's owner. The owner's +public key is part of the contract's parameters.
+The contract would summarize its state by returning a list of post identifiers, +and the state delta would be a list of new posts. The contract would apply the +delta by appending the new posts to its list of posts. The contract may have +a limit on the number of posts it can store, in which case it would remove old +posts to make room for new ones.
+Freenet Contracts can be written in any programming language that compiles to +WebAssembly, but as Freenet is written in Rust it is currently the best supported +language for writing contracts.
+ContractInterface
TraitRust contracts implement the ContractInterface
trait, which defines the
+functions that the core calls to interact with the contract. This trait is
+defined in the
+freenet-stdlib.
/// # ContractInterface
+///
+/// This trait defines the core functionality for managing and updating a contract's state.
+/// Implementations must ensure that state delta updates are *commutative*. In other words,
+/// when applying multiple delta updates to a state, the order in which these updates are
+/// applied should not affect the final state. Once all deltas are applied, the resulting
+/// state should be the same, regardless of the order in which the deltas were applied.
+///
+/// Noncompliant behavior, such as failing to obey the commutativity rule, may result
+/// in the contract being deprioritized or removed from the p2p network.
+pub trait ContractInterface {
+ /// Verify that the state is valid, given the parameters.
+ fn validate_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ related: RelatedContracts<'static>,
+ ) -> Result<ValidateResult, ContractError>;
+
+ /// Verify that a delta is valid if possible, returns false if and only delta is
+ /// definitely invalid, true otherwise.
+ fn validate_delta(
+ parameters: Parameters<'static>,
+ delta: StateDelta<'static>,
+ ) -> Result<bool, ContractError>;
+
+ /// Update the state to account for the new data
+ fn update_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ data: Vec<UpdateData<'static>>,
+ ) -> Result<UpdateModification<'static>, ContractError>;
+
+ /// Generate a concise summary of a state that can be used to create deltas
+ /// relative to this state.
+ fn summarize_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ ) -> Result<StateSummary<'static>, ContractError>;
+
+ /// Generate a state delta using a summary from the current state.
+ /// This along with [`Self::summarize_state`] allows flexible and efficient
+ /// state synchronization between peers.
+ fn get_state_delta(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ summary: StateSummary<'static>,
+ ) -> Result<StateDelta<'static>, ContractError>;
+}
+The ContractInterface
trait is a low-level "Layer 0" API that provides direct
+access to the contract's state and parameters. This API is useful for contracts
+that require fine-grained control over their state, but can be cumbersome.
Soon we will provide higher-level APIs on top of Layer 0 that will sacrifice +some flexibility for ease of contract implementation.
+ +In Freenet, Delegates are software components that can act on the user's behalf. +Think of them as a more sophisticated version of a web browser's local storage, +with similarities to Unix "Daemons". Operating within the Freenet core on your +device, Delegates are a secure and flexible mechanism for managing private data, +such as cryptographic keys, tokens, and passwords, and executing complex tasks.
+Delegates interact with various components within Freenet, including Contracts, +User Interfaces, and other Delegates. They can also communicate directly with +the user, such as to request user permissions or notify the user of events.
+Implemented in WebAssembly and adhering to the +DelegateInterface +trait, Delegates seamlessly integrate within the Freenet network, operating +securely on your devices.
+Delegates communicate with Contracts, other Delegates, and UIs by passing +messages, similar to the actor +model.
+The Freenet Core makes sure that for any incoming message, whether it's from +another Delegate, a User Interface, or a Contract update, the receiver knows who +the sender is. This allows delegates to verify the behavior of any component +they interact with, and decide if they can be trusted.
+Delegates have a wide variety of uses:
+A key manager delegate manages a user's private keys. Other components can +request that this Delegate sign messages or other data on their behalf.
+An inbox delegate maintains an inbox of messages sent to the user in an +email-like system. It retrieves messages from an inbox Contract, decrypts +them, and stores them locally where they can be accessed by other components +like a user interface.
+A contacts delegate manages a user's contacts. It can store and retrieve +contact information, and can be used by other components to send messages to +contacts.
+An alerts delegate watches for events on the network, such as a mention +of the user's name in a discussion, and notifies the user of these events +via an alert.
+Moreover, Delegates can securely synchronize with identical Delegate instances +running on other devices controlled by the user, such as a laptop, phone, or +desktop PC. This synchronization, facilitated through a shared secret private +key provided by the user, allows the Delegates to communicate securely, acting +as both backups and replicas of each other through Freenet's peer-to-peer +network.
+Delegates have much in common with Service Workers in +the web browser ecosystem. Both are self-contained software modules, running +independently of the user interface and performing complex tasks on behalf of +the user.
+However, Delegates are even more powerful. While Service Workers can +store data and interact with components within the scope of the web browser and +its pages, Delegates can talk to other Delegates in the same device, or with +other Delegates running elsewhere via Freenet's peer-to-peer network.
+ +Delegates, contracts, and user interfaces (UIs) each serve distinct roles in the +Freenet ecosystem. Contracts control public data, or "shared +state". Delegates act as the user's agent and can store private +data on the user's behalf, while User Interfaces provide an interface +between these and the user through a web browser. UIs are distributed through +the P2P network via contracts.
+ +The Freenet Core is the software that enables a user's computer to connect to +the Freenet network. Its primary functions are:
+Built with Rust, the core is designed to be compact (ideally under 5 MB), +efficient, and capable of running on a variety of devices such as smartphones, +desktop computers, and embedded devices.
+ +On the normal web, a user might visit https://gmail.com/
, their browser
+will download the Gmail user interface which then runs in their browser and connects back to the Gmail servers.
On Freenet the user interface is downloaded from a Freenet contract, and it +interacts with contracts and delegates by sending messages +through the Freenet core.
+ +These UIs are built using web technologies such as HTML, CSS, and JavaScript, +and are distributed over Freenet and run in a web browser. UIs can create, +retrieve, and update contracts through a WebSocket connection to the local +Freenet peer, as well as communicate with delegates.
+Because UIs run in a web browser, they can be built using any web framework, +such as React, Angular, Vue.js, Bootstrap, and so on.
+ +Freenet contracts must implement the contract interface from stdlib/rust/src/contract_interface.rs:
+/// # ContractInterface
+///
+/// This trait defines the core functionality for managing and updating a contract's state.
+/// Implementations must ensure that state delta updates are *commutative*. In other words,
+/// when applying multiple delta updates to a state, the order in which these updates are
+/// applied should not affect the final state. Once all deltas are applied, the resulting
+/// state should be the same, regardless of the order in which the deltas were applied.
+///
+/// Noncompliant behavior, such as failing to obey the commutativity rule, may result
+/// in the contract being deprioritized or removed from the p2p network.
+pub trait ContractInterface {
+ /// Verify that the state is valid, given the parameters.
+ fn validate_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ related: RelatedContracts<'static>,
+ ) -> Result<ValidateResult, ContractError>;
+
+ /// Verify that a delta is valid if possible, returns false if and only delta is
+ /// definitely invalid, true otherwise.
+ fn validate_delta(
+ parameters: Parameters<'static>,
+ delta: StateDelta<'static>,
+ ) -> Result<bool, ContractError>;
+
+ /// Update the state to account for the new data
+ fn update_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ data: Vec<UpdateData<'static>>,
+ ) -> Result<UpdateModification<'static>, ContractError>;
+
+ /// Generate a concise summary of a state that can be used to create deltas
+ /// relative to this state.
+ fn summarize_state(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ ) -> Result<StateSummary<'static>, ContractError>;
+
+ /// Generate a state delta using a summary from the current state.
+ /// This along with [`Self::summarize_state`] allows flexible and efficient
+ /// state synchronization between peers.
+ fn get_state_delta(
+ parameters: Parameters<'static>,
+ state: State<'static>,
+ summary: StateSummary<'static>,
+ ) -> Result<StateDelta<'static>, ContractError>;
+}
+Parameters
, State
, and StateDelta
are all wrappers around simple [u8]
byte arrays for maximum efficiency and flexibility.
In the (hopefully) near future we'll be adding the ability for contracts to read each other's state while validating and updating their own, see issue #167 for the latest on this.
+ +The Antiflood Token System (AFT) is a decentralized system aimed to provide a +simple, but general purpose solution to flooding, denial-of-service attacks, +and spam.
+AFT allows users to generate tokens through a "token generator", which is +created by completing a "hard" task, such as making a donation to Freenet. +Tokens are generated at a fixed rate and can be utilized to perform activities, +such as sending messages.
+The recipient can specify the required token "tier," with each tier being +generated at different intervals (e.g. 1 minute, 1 hour). This way, if a +recipient experiences a high volume of messages, they can increase the token +tier to make it more challenging to generate, thus reducing the flood.
+The AFT relies on a +TokenDelegate +that implements this DelegateInterface.
+The +TokenAllocContract +keeps track of token assignments to ensure that tokens are not double spent. +New tokens are generated at a fixed rate that depends on the tier required by +the recipient.
+The recipient inbox contract keeps track of inbound messages sent to a +recipient, verifying that each is accompanied by a valid token of the required +tier.
+sequenceDiagram + participant User + participant Application + participant Delegate + participant TokenGeneratorContract + participant RecipientInboxContract + + User->>Application: 1. RequestToken + Application->>Delegate: 2. RequestToken + Delegate->>User: 3. Allocate? + User->>Delegate: 4. approved + Delegate->>TokenGeneratorContract: 5. TokenAllocation + Delegate->>RecipientInboxContract: 6. Message+TokenAllocation + RecipientInboxContract->>TokenGeneratorContract: 7. verify + TokenGeneratorContract->>RecipientInboxContract: 8. verified ++
User requests a token from the application, perhaps by composing a message +and clicking "send" in the UI
+The application requests a token from the delegate via its websocket +connection to the Freenet node
+The delegate requests permission from the user to allocate a token, this +occurs independently of the application, perhaps via an OS-specific +notification mechanism
+The user approves the allocation
+The delegate allocates a token to the token generator contract
+The delegate sends the message and token allocation to the recipient inbox +contract
+The recipient inbox contract verifies that the token allocation is valid +before appending the inbound message to its state
+The token generator contract verifies that the token allocation is valid and +adds it to its list of allocations
+A mechanism to attest the owner of a "target" contract performed some action, +while preserving the owner's anonymity using a blind +signature.
+A typical use would be for the Freenet non-profit to attest that the owner of a +particular contract made a donation to project. The owner can then use this +attestation to prove they made a donation, without revealing their identity to +Freenet or anyone else.
+This contract could then be thought to have a value of the donation amount, +this could then serve as collateral to secure a transaction with a +counterparty, such as a purchase or a loan.
+To do this, the contract would allow the contract owner to temporarily give the +counterparty the ability to "disable" the contract for a mutually agreed period +of time. The parties then conduct their transaction. If the counterparty is +dissatisfied with the transaction then they can disable the contract as +punishment, during which time it cannot be used.
++#![allow(unused)] +fn main() { +let contract_key = // The contract which we want Freenet to attest to +let (blinded_attestation_request, blind_key) = BlindAttestationRequest::blind( + &mut rng, + &contract_key, +); +}
The contract owner then sends the blinded attestation request to Freenet:
++#![allow(unused)] +fn main() { +// URL is https://freenet.org/attestation?blinded_contract_key=4F6oPq... +open_in_browser(&blinded_attestation_request.to_url()); +}
The user then follows the instructions on freenet.org to complete the donation. +Once the donation is complete, freenet.org signs the blinded_contract_key and +sends the attestation response through a response contract in Freenet. This +may also be sent via a browser redirect to the application.
+The attestation consists of:
++ +#![allow(unused)] +fn main() { +struct Attestation { + pub signature : Signature, + pub authorization : Authorization, + pub authorization_sig : Signature, + + /// + fn is_valid(&self) -> Result<Authorization, String> { + if (!signature.verify(&authorization.pubkey, &self.target)) { + return Err("The target's signature is invalid"); + } + + if (!authorization_sig.verify(&freenet_public_key, &self.authorization)) { + return Err("The authorization's signature is invalid"); + } + + Ok(self.authorization) + } +} + +enum Authorization { + FreenetDonation(pubkey : PublicKey, amount_range : (Money, Money), time_range : (Timestamp, Timestamp)), +} + +enum Target { + Contract(ContractKey), +} +}
Software that uses Freenet as a back-end. This includes native software +distributed independenly of Freenet but which uses Freenet as a back-end +(perhaps bundling Freenet), and web applications +that are distributed over Freenet and run in a web browser.
+A contract is WebAssembly code with associated data like the contract state. The +role of the contract is to determine:
+A contract that contains an application or component as state, accessed through +the web proxy.
+For example, if the contract id is
+6C2KyVMtqw8D5wWa8Y7e14VmDNXXXv9CQ3m44PC9YbD2
then visiting
+http://localhost:PORT/contract/web/6C2KyVMtqw8D5wWa8Y7e14VmDNXXXv9CQ3m44PC9YbD2
+will cause the application/component to be retrieved from Freenet, decompressed,
+and sent to the browser where it can execute.
Data associated with a contract that can be retrieved by Applications and
+Components. For efficiency and flexibility, contract state is represented as a
+simple [u8]
byte array.
A delegate is a piece of software that runs on the user's computer and acts on +the user's behalf. Similar to local storage in a web browser, delegates can +store private data on the user's computer and control how it is used. Delegates +can also interact with contracts, applications, and other delegates.
+Represents a modification to some state - similar to a +diff in source code. The exact format of a +delta is determined by the contract. A contract will determine whether a delta +is valid - perhaps by verifying it is signed by someone authorized to modify the +contract state. A delta may be created in response to a State +Summary as part of the State +Synchronization mechanism.
+Data that forms part of a contract along with the WebAssembly code. This is +supplied to the contract as a parameter to the contract's functions. Parameters +are typically be used to configure a contract, much like the parameters of a +constructor function.
+For example, the parameters could contain a hash of the state itself. The +contract would then use it to verify that the state hashes to that value. This +would create a contract that is guaranteed to contain the same state. In the +original Freenet, this was known as a content hash +key.
+Given a contract state, this is a small piece of data that can be used to +determine a delta between two contracts as part of the +state synchronization mechanism. The format +of a state summary is determined by the state's contract.
+Given two valid states for a contract, the state synchronization mechanism +allows the states to be efficiently merged over the network to ensure eventual +consistency.
+Software built on Freenet and distributed through Freenet.
+Applications run in the browser and can be built with tools like React, +TypeScript, and Vue.js. An application may use multiple components and +contracts.
+Applications are compressed and distributed via a container +contract.
+ +Freenet is a distributed, decentralized alternative to the centralized World +Wide Web, designed to unleash a new era of innovation and competition, while +protecting freedom of speech and privacy.
+The heart of Freenet is the Core, +which runs on users' computer, smartphone, or other devices. The Core is +tiny, less than 5 MB, allowing it to be installed in a matter of seconds and +is compatible with a wide range of hardware.
+ +Freenet is a peer-to-peer network, which means +that computers that are part of the network self-organize into a global network +without any central authority, and the work of hosting services is distributed +among the users.
+ +