Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/markdown-format.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
node-version: '24'
cache: 'npm'

- name: Install dependencies
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"check:md": "prettier --check \"**/*.md\" \"**/*.mdx\""
},
"devDependencies": {
"prettier": "^3.0.0"
"prettier": "3.7.4"
},
"prettier": {
"printWidth": 80,
Expand Down
66 changes: 66 additions & 0 deletions website/docs/researchers/rfcs/0000-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
format: md
title: "RFC 0000: Template"
sidebar_label: "0000 Template"
hide_table_of_contents: false
---

> **Original source:**
> [0000-template.md](https://github.com/MinaProtocol/mina/blob/compatible/rfcs/0000-template.md)

## Summary

[summary]: #summary

One paragraph explanation of the feature.

## Motivation

[motivation]: #motivation

Why are we doing this? What use cases does it support? What is the expected
outcome?

## Detailed design

[detailed-design]: #detailed-design

This is the technical portion of the RFC. Explain the design in sufficient
detail that:

- Its interaction with other features is clear.
- It is reasonably clear how the feature would be implemented.
- Corner cases are dissected by example.

## Drawbacks

[drawbacks]: #drawbacks

Why should we _not_ do this?

## Rationale and alternatives

[rationale-and-alternatives]: #rationale-and-alternatives

- Why is this design the best in the space of possible designs?
- What other designs have been considered and what is the rationale for not
choosing them?
- What is the impact of not doing this?

## Prior art

[prior-art]: #prior-art

Discuss prior art, both the good and the bad, in relation to this proposal.

## Unresolved questions

[unresolved-questions]: #unresolved-questions

- What parts of the design do you expect to resolve through the RFC process
before this gets merged?
- What parts of the design do you expect to resolve through the implementation
of this feature before merge?
- What related issues do you consider out of scope for this RFC that could be
addressed in the future independently of the solution that comes out of this
RFC?
131 changes: 131 additions & 0 deletions website/docs/researchers/rfcs/0001-banlisting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
format: md
title: "RFC 0001: Banlisting"
sidebar_label: "0001 Banlisting"
hide_table_of_contents: false
---

> **Original source:**
> [0001-banlisting.md](https://github.com/MinaProtocol/mina/blob/compatible/rfcs/0001-banlisting.md)

# Summary

[summary]: #summary

Punish peers by refusing to connect to their IP when they misbehave.

# Motivation

[motivation]: #motivation

Our software receives diffs, transactions, merkle tree components, etc from
other peers in the network. Much of this is authenticated, meaning we know what
the resulting hash of some object must be. This happens for the
`syncable_ledger` queries and the staged ledger aux data. When a peer sends us
data that results in a state where the hash doesn't match, we know that the peer
was dishonest or buggy. Some other instances of misbehavior that we want to
punish with a ban:

- A received SNARK fails to verify
- An external transition was invalid for any of a number of reasons
- A VRF proof fails to verify

When a node misbehaves, typically it is trying to mount an attack, often a
denial of service attack. We can mitigate the effectiveness of these attempts by
just ignoring that node's messages.

# Detailed design

[detailed-design]: #detailed-design

The basic design is pretty obvious: when a peer misbehaves, notice this, add
their IP to a list, and refuse to communicate with that IP for some amount of
time.

For this we have a persistent table mapping IPs to ban scores.

Introduce the banlist:

```ocaml
module type Banlist_intf = sig
type t

type ban =
{ host: string
; score: int
; reason: string option
; remaining_dur: Time.Span.t }

val record_misbehavior : t -> host:string -> score:int -> ?reason:string -> unit

val ban : t -> host:string -> ?reason:string -> dur:Time.Span.t -> unit

val unban : t -> host:string -> unit

val bans : t -> ban list

val lookup_score : t -> host:string -> int option

val flush : t -> unit Deferred.t
end
```

First, where the code currently has `TODO: punish` or `Logger.faulty_peer`, we
should insert a call to `record_misbehavior`. When the score for a host exceeds
some threshold, the banlist will make sure that:

- The banned hosts won't show up as a result of querying the membership layer
for peers
- RPC connections from those IPs will be rejected.

The banlist should be persistent, and the CLI should allow manually
adding/removing IPs from the banlist:

```
mina client ban add IP duration
mina client ban remove IP
mina client ban list
```

By default, bans will last for 1 day.

# Drawbacks

[drawbacks]: #drawbacks

In the case of bugs and not dishonesty, this could really cause chaos. In the
worst case, the network can become totally disconnected and no peer will
willingly communicate with any other for very long.

# Rationale and alternatives

[rationale-and-alternatives]: #rationale-and-alternatives

It's not clear what the ideal punishment for misbehaving nodes is. A 1-day IP
ban limits most opportunities for DoS, and bitcoin does it, so it seems
reasonable. The main alternative is a permaban, but this is unnecessarily harsh.
Someone else is probably going to reuse that IP soon enough.

A more complex system could haves nodes sharing proofs of peer misbehavior,
which would enable trustless network-wide banning. This would need a fair amount
of work for probably not much gain.

# Prior art

[prior-art]: #prior-art

Bitcoin, when handling network messages from a peer, is careful to check a
variety of conditions to ensure the message conforms to the protocol. When a
check fails, a "ban score" is added to. When the ban score reaches a given
threshold (default 100), the node's IP is banned for a default of 24 hours. Some
checks are insta-bans (most causes of invalid blocks). See in the bitcoin core
source:

- `src/validation.cpp`, grep for `state.DoS`
- `src/net_processing.cpp`, grep for `Misbehaving`

# Unresolved questions

[unresolved-questions]: #unresolved-questions

- Is there any reason to have a more sophisticated ban policy?
79 changes: 79 additions & 0 deletions website/docs/researchers/rfcs/0002-branch-prefixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
format: md
title: "RFC 0002: Branch Prefixes"
sidebar_label: "0002 Branch Prefixes"
hide_table_of_contents: false
---

> **Original source:**
> [0002-branch-prefixes.md](https://github.com/MinaProtocol/mina/blob/compatible/rfcs/0002-branch-prefixes.md)

# Summary

[summary]: #summary

Organize branches by categories of work using and standardizing prefixes.

# Motivation

[motivation]: #motivation

As our repository continues to grow, so will our number of branches. As we begin
to move towards having branches for releases, release candidates, bug fixes, and
new features, and rfcs, we will need the ability to quickly understand which of
these categories a given branch falls into. On top of this, categorizing by
prefix will allow us to seperate name conflicts so that branch names will only
conflict if the both the category and the name are the same.

# Detailed design

[detailed-design]: #detailed-design

Moving forward, all branch names, with the exception of master, will be prefixed
by a category identifier. These branch names will all follow the format
"<category>/<name>", where name is a description of what the branch actually
contains.

These are the categories which branches will fall into:

- feature (a new feature to the codebase)
- fix (a bug fix of existing features)
- rfc (a new rfc to be discussed)
- release (a branch with the latest version of a specific release target)
- release-candidate (a branch for locking and testing a potential future release
before we finalize it)
- tmp (for ad-hoc, temporary, miscellaneous work)

These branch categories can be extended as new types of branches are required.
For instance, in the future, we may want to have "environment" branches, where
pushing to an "env/..." branch will kick off some CI to deploy the code at that
branch to an environment. For example: push "feature/some-experiment" to
"env/testbed" to test it in a cluster in the cloud, or push
"release-candidate/beta" to "env/staging" to test a release candidate for
regressions.

# Drawbacks

[drawbacks]: #drawbacks

The main drawback will be the initial migration. We have many branches out in
the wild that are not prefixed yet, so there may be some confusion while we
begin to adopt the new branch naming scheme, and before we can finish cleaning
up the old branches.

# Rationale and alternatives

[rationale-and-alternatives]: #rationale-and-alternatives

I'm not aware of any alternatives for managing this. Releases are managed
through version tags, but the release branches discussed here are really just a
layer on top of that, intended to represent the latest version of a specific
release cycle (version tags should still be used).

# Unresolved questions

[unresolved-questions]: #unresolved-questions

- How should we manage the migration towards using these new branches? Should we
do one mass branch renaming, or should we remove old branches over time,
pruning them as we no longer need them?
Loading
Loading