Architecture
- Nikita Puzankov
- Vadim Reutskiy
Conceptual View
This section describes the object model of the design.
Layers
According to Dan Boneh Blockchain applications may be divided into four layers:
3 | User Interface |
2 | Applications |
1.5 | Compute Layer |
1 | Consensus Layer |
We will use this classifications to group Iroha components and 3rd party components that can be integrated with Iroha components.
Components
Layer | Components | Description |
User Interface | Iroha Clients + 3rd Party Clients Web/Mobile/CLI | User Facing Services |
Applications | Iroha Modules + Custom Iroha Special Instructions | Run on blockchain computer |
Compute Layer | Iroha + Iroha Modules + Iroha Special Instructions | Application logic is encoded in a program that runs on blockchain • Rules are enforced by a public program (public source code) ➔ transparency: no single trusted 3rd party • The APP program is executed by parties who create new blocks ➔ public verifiability: anyone can verify state transitions |
Consensus Layer | Iroha Sumeragi | A public data structure (ledger) that provides:
|
@startuml cloud "User Interface" { [Mobile Application] [Web Application] [Command Line Interface] } database "Compute Layer" { [Iroha] node "Applications" { [Iroha Substrate] } folder "Consensus" { [Sumeragi] } } [Mobile Application] --> [Iroha] [Web Application] --> [Iroha] [Command Line Interface] --> [Iroha] @enduml
Application Programming Interface
Functionality | Provider | Description |
---|---|---|
Submission of Iroha Special Instructions | Clients | Clients receive declaration of desired actions from users in form of Iroha Special Instructions. They build a Transaction from them, use User's cryptographics keys to Sign it (optionally?) and send them to Iroha. |
Sending of Iroha Queries | Clients | Clients receive declaration of desired search results from users in form of Iroha Queries. They build a Request from them, use User's cryptographics keys to Sign it (optionally) and send them to Iroha. |
Execution of Iroha Special Instructions | Iroha | Iroha receives Transactions from Clients and process them in cooperation with Applications and Consensus. More on that in Process View Section. |
Execution of Iroha Queris | Iroha | Iroha receives Queries from Clients and execute them. More on that in Process View Section. |
Process View
This section describes the activities of the system, captures the concurrency and synchronization aspects of the design.
Clients ↔ Peers Communications
Let's start with Iroha Peers - as described in WhitePaper, Iroha as a system is build on top of a Peer to Peer Network.
So by Peer we will assume every Iroha instance up and running.
@startuml 'default top to bottom direction :User Interface: --> (Submit Iroha Special Instruction) :User Interface: --> (Send Iroha Query) @enduml
So basically we have two main interaction scenarios:
Submission of Iroha Special Instructions
Every User Interface will use `iroha-client` under the hood, so we will look at the sequence with it:
@startuml actor "User" as user participant "Iroha Clinet" as client participant "Iroha Network" as network participant "Iroha" as iroha participant "Transactions Queue" as queue user -> client: submit(Instruction) client -> client: build_transaction(Instruction) client -> client: sign(Transaction) client -> network: send(Transaction) network -> iroha: request iroha -> iroha: accept(Transaction) alt successful case iroha -> queue: push(Transaction) iroha -> network: response(Ok) network -> client: Ok client -> user: Confirmation else some kind of failure iroha -> network: response(Error) network -> client: Error client -> user: Error Message end @enduml
Sending Iroha Queries
@startuml actor "User" as user participant "Iroha Clinet" as client participant "Iroha Network" as network participant "Iroha" as iroha participant "World State View" as view user -> client: request(Query) client -> client: sign(Query) client -> network: send(Query) network -> iroha: request iroha -> view: execute(Query) alt successful case view -> iroha: QueryResult iroha -> network: response(Ok(QueryResult)) network -> client: Ok(QueryResult) client -> user: Result else some kind of failure iroha -> network: response(Error) network -> client: Error client -> user: Error Message end @enduml
Peer ↔ Peer Communications
In this section we will look at Peer to Peer communications in different aspects:
Iroha Qeuries Processing
Let's start from the quite simple Iroha Queries Processing.
@startuml start :receive Query; if (Authority has enough permissions?) then (yes) :lock World State View; :gather Data; :return Result; else (no) :return Error; endif stop @enduml
Iroha Transactions Processing
In this section we will cover only Transactions related part of the whole End to End process of Iroha Special Instructions execution.
Let's start from sequence:
@startuml participant "Iroha Network" as network participant "Torii" as torii participant "Transactions Queue" as queue network -> torii: request torii -> torii: accept(Transaction) alt successful case torii -> queue: push(Transaction) torii -> network: response(Ok) else some kind of failure torii -> network: response(Error) end @enduml
You already see this as a part of Submission of Iroha Special Instructions. Now we introduce Torii - which is Iroha Entity responsible for Network requests and Connections handling.
Queue is like a portal between Torii and another and the most important part of Iroha - Consensus.
Blocks Processing
Consensus works with group of Transactions called Blocks. The whole set of actions that it does with them too big so let's describe each item one by one.
Validation
We will briefly discuss roles that Peer can have, for more information read the White Paper.
In this case we will mainly consider Peer in a `Leader` role. We also will use `Sumeragi` as the only supported by the moment implementation of Consensus in Iroha.
@startuml start :round; if (Queue has transaction to vote) then (yes) if (Peer has the Leader role) then (yes) :build PendingBlock; :lock World State View; :validate PendingBlok; :send VotingBlock messages to peers; else (no) :send transactions to the leader; endif endif stop @enduml
As you can see, validation triggers next Consensus step.
Voting
The science behind Consensus (and Sumeragi) is fully described in the White Paper.
We will look at the high level and simple case of voting here:
@startuml participant "Leader Peer" as leader participant "Voting Peers" as peers participant "Proxy Tail" as proxy leader -> peers: BlockCreated peers -> peers: validate(BlockCreated) alt successful case peers -> proxy: BlockSigned alt enough signatures proxy -> leader: BlockCommited proxy -> peers: BlockCommited proxy -> proxy: commit(block) end end @enduml
As we can see - in simple cases we just sign valid Blocks by Voting Peers and then move to the next stage.
Commitment
This stage involves new Iroha entity - Kura in cooperation with already familiar to you World State View.
@startuml participant "Consensus (Sumeragi)" as consensus participant "Kura" as kura participant "Storage" as storage participant "World State View" as view consensus -> kura: commit(ValidBlock) kura -> storage: store(ValidBlock) alt successful case kura -> view: put(CommitedBlock) end @enduml
Synchronization
Some Peers may be "out of work" because of network or other issues. New Peers may be added. All of them need a mechanism to receive already committed blocks and stay in sync with Ledger.
More on details in the White Paper and Block Synchronization RFC
@startuml participant "Blocks Synchronizer" as synchronizer participant "Peers" as peers participant "Consensus (Sumeragi)" as consensus synchronizer -> peers: LatestBlock alt LatestBlock is next to the the current state peers -> consensus: commit(LatestBlock) end @enduml
Development View
This section describes the static organization or structure of the software in its development of environment.
. ├── Cargo.lock ├── Cargo.toml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── docker-compose-single.yml ├── docker-compose.yml ├── Dockerfile ├── Dockerfile.debug ├── iroha ├── iroha_2_whitepaper.md ├── iroha_client ├── iroha_client_cli ├── iroha_client_no_std ├── iroha_macro ├── iroha_network ├── iroha_substrate ├── LICENSE ├── MAINTAINERS.md ├── README.md ├── scripts └── target
Iroha repository consist of one Iroha cargo workspace.
This workspace compose different crates:
Crate | Type | Description |
---|---|---|
iroha | bin | Main Iroha Application for Peers instantiations. |
iroha_network | lib | Iroha Networking library for encapsulation of protocols. |
iroha_macro | lib | Library with Iroha related macroses (attribute and derive). |
iroha_client | lib | Library with Clients Facing (for User Interfaces, Applications and Peers) API. |
iroha_client_cli | bin | Command Line Interface wrapper on top of iroha_client. |
Physical View
This section describes the mapping of software onto hardware and reflects its distributed aspect.
@startuml cloud "Leader Peer" as leader cloud "Voting Peer1" as voting1 cloud "Voting Peer2" as voting2 cloud "Proxy Tail" as proxy leader -- voting1 leader -- voting2 leader -- proxy voting1 -- leader voting1 -- voting2 voting1 -- proxy voting2 -- voting1 voting2 -- leader voting2 -- proxy proxy -- voting1 proxy -- voting2 proxy -- leader @enduml
As you can see - Peers Deployment is Cloud Native. Peers deployment via `docker-compose` can be used as an example:
version: "3.3" services: iroha: build: context: ./ dockerfile: Dockerfile.debug image: iroha:debug environment: TORII_URL: iroha:1337 TORII_CONNECT_URL: iroha:8888 IROHA_PUBLIC_KEY: '{"inner": [207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}' IROHA_PRIVATE_KEY: '{"inner": [19, 158, 252, 4, 218, 222, 30, 200, 21, 72, 109, 226, 132, 255, 6, 22, 159, 135, 12, 116, 227, 47, 82, 250, 30, 89, 89, 208, 245, 232, 114, 42, 207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}' IROHA_TRUSTED_PEERS: '[{"address":"iroha:1337", "public_key":{"inner": [207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}}, {"address":"iroha2:1338", "public_key": {"inner": [78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}}, {"address": "iroha3:1339", "public_key": {"inner": [106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}}, {"address": "iroha4:1340", "public_key": {"inner": [201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}}]' ports: - "1337:1337" iroha2: depends_on: - iroha image: iroha:debug environment: TORII_URL: iroha2:1338 TORII_CONNECT_URL: iroha2:8889 IROHA_PUBLIC_KEY: '{"inner": [78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}' IROHA_PRIVATE_KEY: '{"inner": [78, 231, 15, 158, 16, 4, 82, 126, 21, 219, 201, 40, 84, 34, 60, 215, 58, 143, 155, 187, 20, 27, 115, 137, 161, 120, 250, 70, 194, 80, 66, 87, 78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}' IROHA_TRUSTED_PEERS: '[{"address":"iroha:1337", "public_key": {"inner": [207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}}, {"address":"iroha2:1338", "public_key": {"inner": [78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}}, {"address": "iroha3:1339", "public_key": {"inner": [106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}}, {"address": "iroha4:1340", "public_key": {"inner": [201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}}]' ports: - "1338:1338" iroha3: depends_on: - iroha image: iroha:debug environment: TORII_URL: iroha3:1339 TORII_CONNECT_URL: iroha3:8890 IROHA_PUBLIC_KEY: '{"inner": [106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}' IROHA_PRIVATE_KEY: '{"inner": [73, 50, 145, 119, 184, 60, 237, 18, 5, 49, 208, 121, 40, 85, 139, 221, 27, 141, 251, 233, 30, 178, 143, 245, 214, 123, 113, 166, 3, 6, 124, 247, 106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}' IROHA_TRUSTED_PEERS: '[{"address":"iroha:1337", "public_key": {"inner": [207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}}, {"address":"iroha2:1338", "public_key": {"inner": [78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}}, {"address": "iroha3:1339", "public_key": {"inner": [106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}}, {"address": "iroha4:1340", "public_key": {"inner": [201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}}]' ports: - "1339:1339" iroha4: depends_on: - iroha image: iroha:debug environment: TORII_URL: iroha4:1340 TORII_CONNECT_URL: iroha4:8891 IROHA_PUBLIC_KEY: '{"inner": [201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}' IROHA_PRIVATE_KEY: '{"inner": [59, 70, 4, 158, 228, 9, 171, 131, 41, 157, 247, 31, 156, 94, 85, 52, 197, 131, 155, 26, 112, 192, 166, 50, 82, 111, 159, 14, 95, 15, 70, 30, 201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}' IROHA_TRUSTED_PEERS: '[{"address":"iroha:1337", "public_key": {"inner": [207, 157, 30, 3, 197, 179, 35, 16, 222, 95, 102, 27, 234, 80, 45, 44, 152, 242, 69, 245, 24, 125, 189, 215, 62, 200, 92, 14, 37, 234, 246, 64]}}, {"address":"iroha2:1338", "public_key": {"inner": [78, 192, 204, 27, 87, 91, 61, 147, 44, 246, 136, 104, 210, 72, 163, 26, 201, 143, 210, 62, 56, 33, 48, 182, 101, 14, 108, 235, 51, 94, 127, 209]}}, {"address": "iroha3:1339", "public_key": {"inner": [106, 192, 132, 99, 17, 107, 23, 45, 151, 112, 32, 242, 143, 142, 111, 57, 20, 151, 83, 12, 215, 253, 103, 126, 111, 96, 101, 17, 93, 110, 164, 255]}}, {"address": "iroha4:1340", "public_key": {"inner": [201, 179, 39, 127, 156, 2, 24, 107, 36, 178, 31, 0, 78, 108, 75, 196, 210, 113, 6, 41, 57, 7, 84, 173, 197, 196, 35, 59, 0, 14, 179, 130]}}]' ports: - "1340:1340"
Scenarios
Version | Date | Comment |
---|---|---|
Current Version (v. 26) | Aug 24, 2020 06:55 | Vadim Reutskiy |
v. 25 | Aug 24, 2020 06:53 | Vadim Reutskiy |
v. 24 | Aug 24, 2020 06:53 | Vadim Reutskiy |
v. 23 | Aug 24, 2020 06:52 | Vadim Reutskiy |
v. 22 | Aug 24, 2020 06:51 | Vadim Reutskiy |
v. 21 | Aug 24, 2020 06:44 | Vadim Reutskiy |
v. 20 | Aug 24, 2020 06:37 | Nikita Puzankov |
v. 19 | Aug 23, 2020 23:27 | Vadim Reutskiy |
v. 18 | Jul 13, 2020 04:19 | Nikita Puzankov |
v. 17 | Jul 09, 2020 03:11 | Nikita Puzankov |
v. 16 | Jul 09, 2020 03:10 | Nikita Puzankov |
v. 15 | Jul 09, 2020 02:42 |
Nikita Puzankov Project Structure |
v. 14 | Jul 09, 2020 02:33 |
Nikita Puzankov Blocks Synchronization |
v. 13 | Jul 09, 2020 02:20 |
Nikita Puzankov Transactions and Blocks processing |
v. 12 | Jul 09, 2020 01:22 |
Nikita Puzankov Iroha Query Processing |
v. 11 | Jul 09, 2020 01:13 |
Nikita Puzankov Sending Iroha Queries |
v. 10 | Jul 09, 2020 01:05 |
Nikita Puzankov Submission of Iroha Special Instructions |
v. 9 | Jul 09, 2020 00:25 |
Nikita Puzankov Plant UML source for components diagram added. |
v. 8 | Jul 09, 2020 00:12 | Nikita Puzankov |
v. 7 | Jul 09, 2020 00:10 | Nikita Puzankov |
v. 6 | Jul 09, 2020 00:06 | Nikita Puzankov |
v. 5 | Jul 08, 2020 23:45 | Nikita Puzankov |
v. 4 | Jul 08, 2020 23:31 | Nikita Puzankov |
v. 3 | Jul 08, 2020 23:31 | Nikita Puzankov |
v. 2 | Jul 08, 2020 23:30 | Nikita Puzankov |
v. 1 | Jul 08, 2020 22:27 | Nikita Puzankov |