-
-
Notifications
You must be signed in to change notification settings - Fork 105
Description
Overview
Antiflood tokens increase the cost of abusive behavior like spam and denial of service attacks within Locutus.
To create antiflood tokens, the user must give up something of value to obtain a token generator. A public/private keypair that meets some cryptographically provable criteria - such as a signed certificate of donation to Freenet. This generator releases new tokens at regular time intervals that depend on the token tier. The lowest tier, 30-second tokens, are released every 30 seconds. Higher tiers release less frequently: 1 minute, 10 minutes, 30 minutes, 1 hour, 2 hours, 4 hours, 12 hours, or 1 day.
Other systems can require that a token of some minimum tier be issued as a condition of some action like adding a message to an inbox. In the event of bad behavior by the generator owner, the recipient can create a complaint, which will be visible to anyone interacting with the generator.
Initially, this will be a centralized solution. The user must make a cryptographically blinded donation to Freenet to obtain a token generator. In the future, we will provide a decentralized on-network way to create new token generators. We're still at the ideation stage with that, but it will not be based on proof-of-work.
Token Generator
Creating a Token Generator
- The user creates
generator_key_pairand blindsgeneratorPublicKeyto getblind(generator_public_key)before sending it tohttps://freenet.org/donations - Freenet's donation system selected a
donation_key_pairbased on the donation amount - Donation system signs
blind(generator_public_key)withdonation_private_keyto producesigned(donation_public_key, blind(generator_public_key)) signed(donation_public_key, blind(generator_public_key))is sent back to the user- The user unblinds it to obtain
signed(donation_public_key, generator_public_key), this is the initialization certificate and can be used to prove that the generator has been initialized with a donation
Token Generator Contract
The Token Generator Contract keeps track of tokens that have been assigned
Contract State
The token contract state is a set of token assignments organized by tier (frequency of token release), and then the time the token is released.
The contract verifies that the release times for a tier match the tier. For example, a 15:30 UTC release time isn't permitted for hour_1 tier, but 15:00 UTC is permitted.
Note: Conflicting assignments for the same time slot are not permitted and indicate that the generator is broken or malicious.
struct TokenContractParameters {
generator_public_key : PublicKey,
current_date_utc : Date,
}
struct TokenContractState {
/// A list of issued tokens
tokens_by_tier : HashMap<Tier, HashMap<DateTime, TokenAssignment>>,
}
struct TokenAssignment {
tier : Tier,
issue_time : DateTime,
/// The assignment, the recipient decides whether this assignment
/// is valid based on this field. This will often be a PublicKey.
assigned_to: [u8],
/// `(tier, issue_time, assigned_to)` must be signed
/// by `generator_public_key`
signature: Signature,
}
enum Tier {
minute_1, minute_10, minute_30, hour_1,
hour_2, hour_4, hour_12, day_1
}Requirements
For the TokenAssignment to be valid only one TokenAssignment must exist for a given issue_time and tier
Token assignment and verification
For example, consider a contract representing a message inbox, where senders must spend a token to add a message to the inbox. The inbox decides what tier of token is required, this should be made known to senders.
struct InboxContractState {
messages : Vec<InboxMessage>,
}
struct InboxMessage {
message: String,
assignment: TokenAssignment,
/// `(message, assignment)` signed by generator's public key
signature: Signature,
}- The sender creates an
InboxMessageincluding a validTokenAssignment - The sender attempts to modify the inbox to add the new message
- The
InboxContractverifies that the tier is high enough and the assignment signature matches - The
InboxContractverifies that the assignment is valid by checking the relevantTokenContractState, ignoring it if it isn't
Complaints
Generator Complaint Contract
A contract that maintains a list of valid complaints for a generator - complaints can be created by a token recepient. Tokens from a generator with an excessive number of complaints may be rejected. The recepient is responsible for adding complaints to this contract.
struct GeneratorComplaintsParameters {
generator_public_key: PublicKey,
}
struct GeneratorComplaintsState {
complaints : HashMap<DateTime, HashMap<Tier, Complaint>>,
}
struct Complaint {
/// A valid assignment is required for a complaint
assignment: TokenAssignment,
/// Reason for the complaint
reason: String,
/// `(assignment, reason)` must be signed by the token
/// recipient to be a valid complaint
recepient_signature : Signature,
}Enhancements
-
We should randomize the daily changeover time for
current_date_utcbased on thegenerator_public_keyto avoid a synchronized network change at 0:00 UTC. -
assigned_tofield inTokenAssignmentis redundant in anInboxMessagebecause we already know theassigned_tohere. We should avoid wasting these bytes. -
Token recipients can specify a maximum token age, preventing passive accumulation of a large number of tokens over time
-
A duplicate token assignment is evidence of malicious behavior by the generator owner and will disable the token generator
Conclusion
We've now described a mechanism for generating scarce tokens that can be spent to gain access to potentially floodable resources like a message inbox.