npm package: @scintilla-network/quorums
Description: Quorums connector and primitives for the Scintilla Network
Author: Scintilla Labs
Latest version: 1.0.1

# @scintilla-network/quorums

## Overview

`@scintilla-network/quorums` is a library designed to facilitate the creation, management, and communication of decentralized quorums within the Scintilla Network.  

This library includes classes and utilities for such.  


- By having each peers registered with their identity, each peer can be identified
- Any known connections is added to the peer list and its state changes accross time. It shall be taken into account that peers ip addresses can be reused by other peers (like with AWS).
- Therefore, peers are identified with `{moniker}::{ip}:{port}` system (that's the network identifier for peer).


## Peers

Peers in the system are identified by their moniker, ip address and port (e.g. `alice::52.23.30.1:8900`).  
The moniker allows for secure exchange of messages between peers as the identity contains the public key of the peer.
The ip address and port are used to establish a connection between peers and to locate them in the network.

Additionally, peers can be more specifically identified by theit quorum cluster they belong to (e.g. `alice::52.23.30.1:8900@scintilla`).

## Installation

To install `@scintilla-network/quorums`, use npm:

```bash
npm install @scintilla-network/quorums
```

## Usage

Here's an example of how to create a quorum network, add identities, and start the network:

### QuorumNetwork Example

```javascript
import QuorumNetwork from '@scintilla-network/quorums/QuorumNetwork';
import { Identity } from '@scintilla-network/sdk';

const id = {
    parent: null,
    moniker: 'scintilla',
    members: [['core', 1000, 1000, 0, 0, 0, 0]],
    records: {
        modules: {
            'core.identity': {
                actions: {
                    PROPOSAL_CREATE: [{
                        condition: {
                            all: [{ fact: 'identity#parent', operator: 'IN', value: ['sct', 'core', 'scintilla'] }]
                        },
                        type: 'ALLOW'
                    }]
                }
            },
            scintilla: {
                consensus: {
                    members: [['sct.yggdrasil.coordinator', 1000]],
                    type: 'COORDINATOR_PROOF'
                }
            }
        }
    },
    childs: []
};

const qnet = new QuorumNetwork({
    quorum: 'scintilla',
    moniker: 'alice'
});

(async () => {
    // Initialize and start the network, load prior state
    await qnet.init();
    
    // Update identities
    qnet.updateIdentity(new Identity(id));

    // Open the network on port 8900
    // Allow to relay messages to other peers
    await qnet.open(8900);
    
    // Connect to peers, by default, the network will connect to one or all quorum members 
    await qnet.connect();
    
    // Start the network
    await qnet.start();

    console.log({ qnet });
    console.log(qnet.connections);
})();
```

## Components

- **IdentitiesMap**: Manages a collection of identity objects. [Read more](./IdentitiesMap/IdentitiesMap.md)
- **NetRequest**: Represents a network request with capabilities for encryption, signing, and verification. [Read more](./NetRequest/NetRequest.md)
- **NetResponse**: Represents a response to a network request. [Read more](./NetResponse/NetResponse.md)
- **PeerMap**: Manages a collection of peers. [Read more](./PeerMap/PeerMap.md)
- **QuorumIdentity**: Represents an identity within a quorum. [Read more](./QuorumIdentity/QuorumIdentity.md)
- **QuorumMember**: Represents a member within a quorum. [Read more](./QuorumMember/QuorumMember.md)
- **QuorumNetwork**: Manages the overall quorum network, including peer connections and communication. [Read more](./QuorumNetwork/QuorumNetwork.md)
- **QuorumPeer**: Represents a peer in the quorum network. [Read more](./QuorumPeer/QuorumPeer.md)
- **TCPConnection**: Represents a TCP connection. [Read more](./TCPConnection/TCPConnection.md)
- **TCPServer**: Represents a TCP server. [Read more](./TCPServer/TCPServer.md)
- **Queue**: Represents a queue data structure. [Read more](./Queue/Queue.md)
- **Stack**: Represents a stack data structure with message processing capabilities. [Read more](./Stack/Stack.md)
- **QuorumDecision**: Represents a decision made by the quorum, with support for signing and verifying multiple authorizations. [Read more](./QuorumDecision/QuorumDecision.md)
- **QuorumDecisionVote**: Represents a vote on a QuorumDecision. [Read more](./QuorumDecisionVote/QuorumDecisionVote.md)



### IdentitiesMap

Manages a collection of identity objects.

**Example:**

```javascript
import IdentitiesMap from '@scintilla-network/quorums/IdentitiesMap';

const identities = new IdentitiesMap();
identities.set(someIdentity);
const retrievedIdentity = identities.get(someMoniker);
```

### NetRequest

Represents a network request with capabilities for encryption, signing, and verification.

**Example:**

```javascript
import NetRequest from '@scintilla-network/quorums/NetRequest';

const netRequest = new NetRequest({
    source: 'source',
    destination: 'destination',
    method: 'GET',
    path: '/blocks/current',
    payload: [],
});

console.log(netRequest.toHex());
```

### NetResponse

Represents a response to a network request.

**Example:**

```javascript
import NetResponse from '@scintilla-network/quorums/NetResponse';

const netResponse = new NetResponse({
    request: 'someRequestId',
    destination: 'destination',
    source: 'source',
    code: 200,
    payload: [],
});

console.log(netResponse.toHex());
```

### PeerMap

Manages a collection of peers.

**Example:**

```javascript
import PeerMap from '@scintilla-network/quorums/PeerMap';

const peers = new PeerMap();
peers.set('identifier', somePeer);
```

### QuorumIdentity

Represents an identity within a quorum.

**Example:**

```javascript
import QuorumIdentity from '@scintilla-network/quorums/QuorumIdentity';

const quorumIdentity = new QuorumIdentity(someIdentity);
console.log(quorumIdentity.getMembers());
```

### QuorumMember

Represents a member within a quorum.

**Example:**

```javascript
import QuorumMember from '@scintilla-network/quorums/QuorumMember';

const quorumMember = new QuorumMember(someIdentity, someQuorumIdentity);
console.log(quorumMember.getNetworkInfo());
```

### QuorumNetwork

Manages the overall quorum network, including peer connections and communication.

**Example:**

```javascript
import QuorumNetwork from '@scintilla-network/quorums/QuorumNetwork';

const qnet = new QuorumNetwork({
    quorum: 'scintilla',
    moniker: 'alice'
});

await qnet.init();
await qnet.open(8900);
await qnet.connect();
await qnet.start();
```

### QuorumPeer

Represents a peer in the quorum network.

**Example:**

```javascript
import QuorumPeer from '@scintilla-network/quorums/QuorumPeer';

const qp = new QuorumPeer(someQuorumMember);
await qp.connect();
```

### TCPConnection

Represents a TCP connection.

**Example:**

```javascript
import TCPConnection from '@scintilla-network/quorums/TCPConnection';

const conn = new TCPConnection();
await conn.connect({ port: 8888, host: 'localhost' });
conn.send(someData);
```

### TCPServer

Represents a TCP server.

**Example:**

```javascript
import TCPServer from '@scintilla-network/quorums/TCPServer';

const server = new TCPServer();
await server.listen(8888);
server.broadcast(someData);
```

### Queue

Represents a queue data structure.

**Example:**

```javascript
import Queue from '@scintilla-network/quorums/Queue';

const queue = new Queue();
queue.enqueue(someItem);
console.log(queue.dequeue());
```

### Stack

Represents a stack data structure with message processing capabilities.

**Example:**

```javascript
import Stack from '@scintilla-network/quorums/Stack';

const stack = new Stack();
stack.push(someData);
console.log(stack.processMessages());
```

---

### QuorumDecision

Represents a decision made by the quorum, with support for signing and verifying multiple authorizations.

**Example:**

```javascript
import QuorumDecision from '@scintilla-network/quorums/QuorumDecision';

const decision = new QuorumDecision({
    proposer: 'proposer1',
    cluster: 'cluster1',
    quorum: 'quorum1',
    payload: { data: 'test' },
    action: 'ADD_MEMBER',
});
await decision.sign(signer);
console.log(decision.verify());
```

### QuorumDecisionVote

Represents a vote on a QuorumDecision.

**Example:**

```javascript
import QuorumDecisionVote from '@scintilla-network/quorums/QuorumDecisionVote';

const vote = new QuorumDecisionVote({
    decision: 'decision1',
    voter: 'voter1',
    vote: 'YES',
});

console.log(vote.getVote());
```

## Detailed Documentation

For more details on each component, refer to the individual documentation files:

- [IdentitiesMap](./IdentitiesMap/IdentitiesMap.md)
- [NetRequest](./NetRequest/NetRequest.md)
- [NetResponse](./NetResponse/NetResponse.md)
- [PeerMap](./PeerMap/PeerMap.md)
- [QuorumIdentity](./QuorumIdentity/QuorumIdentity.md)
- [QuorumMember](./QuorumMember/QuorumMember.md)
- [QuorumNetwork](./QuorumNetwork/QuorumNetwork.md)
- [QuorumPeer](./QuorumPeer/QuorumPeer.md)
- [TCPConnection](./TCPConnection/TCPConnection.md)
- [TCPServer](./TCPServer/TCPServer.md)
- [Queue](./Queue/Queue.md)
- [Stack](./Stack/Stack.md)
- [QuorumDecision](./QuorumDecision/QuorumDecision.md)
- [QuorumDecisionVote](./QuorumDecisionVote/QuorumDecisionVote.md)