filecoin-project / venus

Filecoin Full Node Implementation in Go
https://venus.filecoin.io
Other
2.06k stars 461 forks source link

Create an architecture diagram #1676

Closed acruikshank closed 5 years ago

acruikshank commented 5 years ago

Description

We would like to have detailed understanding of the go-filecoin's high level architecture. There is currently no good understanding of what perspective to take on the architecture and what it's rules should be.

We have had the concept of an "API" that delineates go-filecoin's interior from, say, network access or the user interface. "API" is in quotes, because the commands also provide a REST API which is not exactly the same.

Porcelain/Plumbing is a good example of a new guiding principal for architecture, but it's not sufficient to structure all the code or inform all architectural decisions.

This issue provides a place to track artifacts of this discussion on their way to becoming normative.

acruikshank commented 5 years ago

This is very high level with almost no detail. What it documents is that porcelain/plumbing provides and interface to protocols. Storage/Mining/Chain are protocols (there could be others). Protocols provide an interface to the network and storage. The diagram suggests that protocols only talk to the API which isn't entirely true.

      ┌─────────────────────────────────────────────────────────────────┐
      │                                                                 │
      │                       Commands / REST API                       │
      │                                                                 │
      └───────────────────────────────▲─────────────────────────────────┘
                                      │
      ┌─────────────────────────┬─────▼─────────────────────────────────┐
      │        Porcelain        │                                       │
      │                         │  Plumbing                             │
      ├─────────────────────────┘                                       │
      │                                                                 │
      └──────────────▲──────────────────────────▲────────────────▲──────┘
                     │                          │                │
      ┌──────────────▼───────────────┐   ┌──────▼──────┐  ┌──────▼──────┐
      │                              │   │             │  │             │
      │                              │   │   Mining    │  │    Chain    │
      │       Storage Protocol       │   │  Protocol   │  │  Protocol   │
      │                              │   │             │  │             │
      │                              │   │             │  │             │
      └──────▲────────────────▲──────┘   └──────▲──────┘  └──────▲──────┘
             │                │                 │                │
      ┌──────▼──────┐  ┌──────▼──────┐   ┌──────▼────────────────▼──────┐
      │             │  │             │   │                              │
      │ filesystem  │  │   bitswap   │   │ Gossip Sub (blocks/messages) │
      │             │  │             │   │                              │
      └─────────────┘  └─────────────┘   └──────────────────────────────┘
phritz commented 5 years ago

Your sketch looks really similar to what I sketched last night (btw what do you use to draw the diagram?). Note i have commands talking to protocols bc of things like client retrieve piece which we want to be synchronous. also mining start and the like. we could route them through an event system but it would be a little awkward though obviously perfectly possible. img_20190123_074307

I think there are some canonical use cases we should be considering for potential architectures eg:

A big question in my mind is what kind of front vs backdoor dependencies we want. Front door dependencies are accessed through the plumbing api. Backdoor dependencies are via shared direct dependency, eg the chain sync protocol has-a chain store that is the same (read-only) chain store the plumbing chain calls use. For example

I can hear an argument that everything that protocols need modulo network is available in plumbing. It makes a certain sense but then it effectively flattens the entire abstraction hierarchy into a single interface inclusive of datastore, signing, various stores, etc etc etc and exposes a lot of stuff in the plumbing api that really nobody should be using eg setting a new heaviest tipset. My gut says that plumbing should expose a set of functionality that is complete for user- and tool-facing features but that is not necessarily complete for protocol implementation. For example the producer side of the heaviest tipset iterators or the interface to write to the chainstore would not be plumbing and instead would form part of a backdoor set of deps shared between plumbing and protocol implementations. (according to this theory, which may be wrong)

Happy to hear disagreement on any or all of this.

phritz commented 5 years ago

notes from conversation with @acruikshank wip:

core apis (misnamed as utils above):

plumbing:

porcelain:

commands:

protocols:

q: sector base, is that core? @acruikshank q: how do commands interact with protocols? @acruikshank

acruikshank commented 5 years ago

New diagram based on comments above:

           ┌──────────┐ ┌───────────┐ ┌──────────┐
           │          │ │Gossip Sub │ │          │                |  | \  /
  Network  │filesystem│ │ (blocks/  │ │ bitswap  │                |  |  \/
           │          │ │ messages) │ │          │                |  |  /\
           └─────▲────┘ └─────▲─────┘ └────▲─────┘                \__/ /  \
                 ├────────────┘            │
           ┌─────▼────┐ ┌───────────┐ ┌────▼─────┐     ┌────────────────────────────┐
           │          │ │           │ │          │     │                            │
Protocols  │ Storage  │ │  Mining   │ │  Chain   │     │    Commands / REST API     │
           │ Protocol │ │ Protocol  │ │ Protocol │     │                            │
           │          │ │           │ │          │     └────────────────────────────┘
           └──────────┘ └───────────┘ └──────────┘                    │
                 │            │             │                         │
                 └──────────┬─┴─────────────┴───────────┐             │
                            ▼                           ▼             ▼
           ┌────────────────────────────────┐ ┌───────────────────┬─────────────────┐
 Internal  │            Core API            │ │     Porcelain     │     Plumbing    │
      API  │                                │ ├───────────────────┘                 │
           └────────────────────────────────┘ └─────────────────────────────────────┘
                            │                                    │
                  ┌─────────┴────┬──────────────┬──────────────┬─┴────────────┐
                  ▼              ▼              ▼              ▼              ▼
           ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
           │            │ │            │ │            │ │            │ │            │
     Core  │  Message   │ │   Chain    │ │ Processor  │ │   Block    │ │   Wallet   │
           │   Store    │ │   Store    │ │            │ │  Service   │ │            │
           │            │ │            │ │            │ │            │ │            │
           └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘
phritz commented 5 years ago

@acruikshank awesome this is looking really good. small suggestions/comments:

phritz commented 5 years ago

@acruikshank can you chime in on the second to last bullet? @anorth is going to use this diagram in a code walk through so we should settle on how we talk about it.

acruikshank commented 5 years ago
           ┌─────────────────────────────────────┐
           │                                     │
  Network  │  network (gosipsub, bitswap, etc.)  │                 | | \/
           │                                     │                 |_| /\
           └─────▲────────────▲────────────▲─────┘
                 │            │            │           ┌────────────────────────────┐
           ┌─────▼────┐ ┌─────▼─────┐ ┌────▼─────┐     │                            │
           │          │ │           │ │          │     │    Commands / REST API     │
Protocols  │ Storage  │ │  Mining   │ │Retrieval │     │                            │
           │ Protocol │ │ Protocol  │ │ Protocol │     └────────────────────────────┘
           │          │ │           │ │          │                    │
           └──────────┘ └───────────┘ └──────────┘                    │
                 │            │             │                         │
                 └──────────┬─┴─────────────┴───────────┐             │
                            ▼                           ▼             ▼
           ┌────────────────────────────────┐ ┌───────────────────┬─────────────────┐
 Internal  │            Core API            │ │     Porcelain     │     Plumbing    │
      API  │                                │ ├───────────────────┘                 │
           └────────────────────────────────┘ └─────────────────────────────────────┘
                            │                                    │
                  ┌─────────┴────┬──────────────┬──────────────┬─┴────────────┐
                  ▼              ▼              ▼              ▼              ▼
           ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
           │            │ │            │ │            │ │            │ │            │
     Core  │  Message   │ │   Chain    │ │ Processor  │ │   Block    │ │   Wallet   │
           │    Pool    │ │   Store    │ │            │ │  Service   │ │            │
           │            │ │            │ │            │ │            │ │            │
           └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘
acruikshank commented 5 years ago

@phritz Everything but the second to last comment should be reflected in the new diagram. As for whether there should be a Core API, the point I'm trying to make in the diagram is that there's a boundary between protocols and the things (stores?) at the bottom. Protocols can depend on those things, but not the other way around. Protocols implement processes, and the things at the bottom provide infrastructure to support those processes.

Wherever we can draw a boundary like this it's a good opportunity to think of it like an API (i.e. ask whether it's user friendly and well tested). That said, I don't feel strongly about formalizing the API beyond formalizing the rules that separate protocols from stores.

phritz commented 5 years ago

awesome thanks @acruikshank . @anorth please close this when you include the diagram above in your doc.

anorth commented 5 years ago

Now in CODEWALK.md