Skip to content

Commit

Permalink
Merge pull request ethereum#241 from jpmorganchase/doc-updates
Browse files Browse the repository at this point in the history
Update docs for Quorum v2.
  • Loading branch information
patrickmn authored Jan 25, 2018
2 parents 0905eda + e76c059 commit 37ccab5
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 248 deletions.
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* [Design](./design.md) - Quorum design overview
* [Privacy](./privacy.md) - Sending private transactions [privacy video](https://vimeo.com/user5833792/review/210456729/8f70cfaaa5)
* [Running](./running.md) - Detailed instructions for running Quorum nodes (see also [Constellation](https://github.com/jpmorganchase/constellation))
* [API](./api.md) - new APIs for interacting with QuorumChain consensus
* [API](./api.md) - new privacy API
100 changes: 0 additions & 100 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,103 +48,3 @@ web3.eth.sendTransaction({
}
});
```


## QuorumChain APIs

Quorum provides an API to inspect the current state of the voting contract.

### `quorum.nodeInfo` returns the quorum capabilities of this node

Example output for a node that is configured as block maker and voter:

```
> quorum.nodeInfo
{
blockMakerAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
blockmakestrategy: {
maxblocktime: 6,
minblocktime: 3,
status: "active",
type: "deadline"
},
canCreateBlocks: true,
canVote: true,
voteAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"
}
```

### `quorum.vote` votes for the given hash to be the canonical head on the current height and returns the tx hash

```
> quorum.vote(eth.getBlock("latest").hash)
"0x16c69b9bdf9f10c64e65dbfe50bc997d2bc1ed321c6041db602908b7f6cab2a9"
```

### `quorum.canonicalHash` returns the canonical hash for the given block height (add 1 for the hash that the current pending block will be based on top of)

```
> quorum.canonicalHash(eth.blockNumber+1)
"0xf2c8a36d0c54c7013246fddebfc29bc881f6f10f74f761d511b5ebfaa103adfa"
```

### `quorum.isVoter` returns whether the given address is allowed to vote for new blocks

```
> quorum.isVoter("0xed9d02e382b34818e88b88a309c7fe71e65f419d")
true
```

### `quorum.isBlockMaker` returns whether the given address is allowed to make blocks

```
> quorum.isBlockMaker("0xed9d02e382b34818e88b88a309c7fe71e65f419d")
true
```

### `quorum.makeBlock` orders the node to create a block bypassing block maker strategy

```
> quorum.makeBlock()
"0x3a07e82a48ab3c19a3d09d247e189e3a3041d1d9eafd2e1515b4ddd5b016bfd9"
```

### `quorum.pauseBlockMaker` (temporary) orders the node to stop creating blocks

```
> quorum.pauseBlockMaker()
null
> quorum.nodeInfo
{
blockMakerAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
blockmakestrategy: {
maxblocktime: 6,
minblocktime: 3,
status: "paused",
type: "deadline"
},
canCreateBlocks: true,
canVote: true,
voteAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"
}
```

### `quorum.resumeBlockMaker` instructs a paused node to begin creating blocks again

```
> quorum.resumeBlockMaker()
null
> quorum.nodeInfo
{
blockMakerAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
blockmakestrategy: {
maxblocktime: 6,
minblocktime: 3,
status: "active",
type: "deadline"
},
canCreateBlocks: true,
canVote: true,
voteAccount: "0xed9d02e382b34818e88b88a309c7fe71e65f419d"
}
```
19 changes: 0 additions & 19 deletions docs/design.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@

# Design

## Consensus algorithm

Quorum introduces a new consensus algorithm called QuorumChain, a majority
voting protocol where a subset of nodes within the network are given the
`voting` role. The voting role allows a node to vote on which block should be the
canonical head at a particular height. The block with the most votes will win
and is considered the canonical head of the chain.

Block creation is only allowed by nodes with the `block maker` role.
A node with this role can create a block, sign the block and put the signature within the `ExtraData` field of the block.
On `block import`, nodes can verify if the block was signed by one of the nodes that have the `block maker` role.

Nodes can be given no role, one of the roles or both roles through command line arguments.
The collection of addresses with special roles is tracked within the QuorumChain smart contract.

QuorumChain is implemented in a smart contract pre-deployed on address `0x0000000000000000000000000000000000000020` and can be found [here](https://github.com/jpmorganchase/quorum/blob/master/core/quorum/block_voting.sol).
Voters and block makers can be added or removed and the minimum number of votes before a block is selected as winner can be configured.


## Public/Private State

Quorum supports dual state:
Expand Down
31 changes: 0 additions & 31 deletions docs/new-block-code-walkthrough.md

This file was deleted.

105 changes: 8 additions & 97 deletions docs/running.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@

# Running Quorum

The following new CLI arguments were introduced as part of Quorum:
A `--permissioned` CLI argument was introduced with Quorum.

```
QUORUM OPTIONS:
--voteaccount value Address that is used to vote for blocks
--votepassword value Password to unlock the voting address
--blockmakeraccount value Address that is used to create blocks
--blockmakerpassword value Password to unlock the block maker address
--singleblockmaker Indicate this node is the only node that can create blocks
--minblocktime value Set minimum block time (default: 3)
--maxblocktime value Set max block time (default: 10)
--permissioned If enabled, the node will allow only a defined list of nodes to connect
```

Expand All @@ -21,9 +14,6 @@ The full list of arguments can be viewed by running `geth --help`.

The first step is to generate the genesis block.

The genesis block should include the Quorum voting contract address `0x0000000000000000000000000000000000000020`.
The code can be generated with [browser solidity](http://ethereum.github.io/browser-solidity/#version=soljson-latest.js) (note, use the runtime code) or using the solidity compiler: `solc --optimize --bin-runtime block_voting.sol`.

The `7nodes` directory in the `quorum-examples` repository contains several keys (using an empty password) that are used in the example genesis file:

```
Expand All @@ -37,37 +27,7 @@ key5 block maker 2
Example genesis file (copy to `genesis.json`):
```json
{
"alloc": {
"0x0000000000000000000000000000000000000020": {
"code": "606060405236156100c45760e060020a60003504631290948581146100c9578063284d163c146100f957806342169e4814610130578063488099a6146101395780634fe437d514610154578063559c390c1461015d57806368bb8bb61461025d57806372a571fc146102c857806386c1ff681461036957806398ba676d146103a0578063a7771ee31461040b578063adfaa72e14610433578063cf5289851461044e578063de8fa43114610457578063e814d1c71461046d578063f4ab9adf14610494575b610002565b610548600435600160a060020a03331660009081526003602052604090205460ff16156100c45760018190555b50565b610548600435600160a060020a03331660009081526005602052604090205460ff16156100c4576004546001141561055e57610002565b61045b60025481565b61054a60043560056020526000908152604090205460ff1681565b61045b60015481565b61045b60043560006000600060006000600050600186038154811015610002579080526002027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630192505b60018301548110156105d75760018301805484916000918490811015610002576000918252602080832090910154835282810193909352604091820181205485825292869052205410801561023257506001805490840180548591600091859081101561000257906000526020600020900160005054815260208101919091526040016000205410155b156102555760018301805482908110156100025760009182526020909120015491505b6001016101a8565b610548600435602435600160a060020a03331660009081526003602052604081205460ff16156100c4578054839010156105e45780548084038101808355908290829080158290116105df576002028160020283600052602060002091820191016105df919061066b565b610548600435600160a060020a03331660009081526005602052604090205460ff16156100c457600160a060020a0381166000908152604090205460ff1615156100f65760406000819020805460ff191660019081179091556004805490910190558051600160a060020a038316815290517f1a4ce6942f7aa91856332e618fc90159f13a340611a308f5d7327ba0707e56859181900360200190a16100f6565b610548600435600160a060020a03331660009081526003602052604090205460ff16156100c4576002546001141561071457610002565b61045b600435602435600060006000600050600185038154811015610002579080526002027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630181509050806001016000508381548110156100025750825250602090200154919050565b61054a600435600160a060020a03811660009081526003602052604090205460ff165b919050565b61054a60043560036020526000908152604090205460ff1681565b61045b60045481565b6000545b60408051918252519081900360200190f35b61054a600435600160a060020a03811660009081526005602052604090205460ff1661042e565b610548600435600160a060020a03331660009081526003602052604090205460ff16156100c457600160a060020a03811660009081526003602052604090205460ff1615156100f65760406000818120600160a060020a0384169182905260036020908152815460ff1916600190811790925560028054909201909155825191825291517f0ad2eca75347acd5160276fe4b5dad46987e4ff4af9e574195e3e9bc15d7e0ff929181900390910190a16100f6565b005b604080519115158252519081900360200190f35b600160a060020a03811660009081526005602052604090205460ff16156100f65760406000819020805460ff19169055600480546000190190558051600160a060020a038316815290517f8cee3054364d6799f1c8962580ad61273d9d38ca1ff26516bd1ad23c099a60229181900360200190a16100f6565b509392505050565b505050505b60008054600019850190811015610002578382526002027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563016020819052604082205490925014156106b8578060010160005080548060010182818154818355818115116106a5578183600052602060002091820191016106a5919061068d565b50506002015b808211156106a157600181018054600080835591825260208220610665918101905b808211156106a1576000815560010161068d565b5090565b5050506000928352506020909120018290555b600082815260208281526040918290208054600101905581514381529081018490528151600160a060020a033316927f3d03ba7f4b5227cdb385f2610906e5bcee147171603ec40005b30915ad20e258928290030190a2505050565b600160a060020a03811660009081526003602052604090205460ff16156100f65760406000819020805460ff19169055600280546000190190558051600160a060020a038316815290517f183393fc5cffbfc7d03d623966b85f76b9430f42d3aada2ac3f3deabc78899e89181900360200190a16100f656",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x02",
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x04",
"0x29ecdbdf95c7f6ceec92d6150c697aa14abeb0f8595dd58d808842ea237d8494": "0x01",
"0x6aa118c6537572d8b515a9f9154be55a3377a8de7991cd23bf6e5ceb368688e3": "0x01",
"0x50793743212c6f01d326957d7069005b912f8215f10c7536be6b10782c6c44cd": "0x01",
"0x38f6c908c5cc7ca668cec2f476abe61b4dbb1df20f0ad8e07ef5dbf6a2f1ffd4": "0x01",
"0x0000000000000000000000000000000000000000000000000000000000000004": "0x02",
"0xaca3b76ed4968740c3180dd7fa37f4aa229a2c758a848f53920e9ccb4c4bb74e": "0x01",
"0xd188ba2dc293670542c1befaf7678b0859e5354a0727d1188b2afb6f47fe24d1": "0x01"
}
},
"0xed9d02e382b34818e88b88a309c7fe71e65f419d": {
"balance": "1000000000000000000000000000"
},
"0xca843569e3427144cead5e4d5999a3d0ccf92b8e": {
"balance": "1000000000000000000000000000"
},
"0x0fbdc686b912d7722dc86510934589e0aaf3b55a": {
"balance": "1000000000000000000000000000"
},
"0x9186eb3d20cbd1f5f992a950d808c4495153abd5": {
"balance": "1000000000000000000000000000"
},
"0x0638e1574728b6d862dd5d3a3e0942c3be47d996": {
"balance": "1000000000000000000000000000"
}
},
"alloc": {},
"coinbase": "0x0000000000000000000000000000000000000000",
"config": {
"homesteadBlock": 0
Expand All @@ -88,25 +48,8 @@ Now we can initialize geth:
geth init genesis.json
```

The storage key for voters and block makers is calculated with `web3.sha3(<256 bit aligned key value> + <256 bit variable index>)`.
The console can be used to calculate the storage key, in this case for vote key 1:
```
> key = "000000000000000000000000ed9d02e382b34818e88b88a309c7fe71e65f419d" + "0000000000000000000000000000000000000000000000000000000000000003"
"000000000000000000000000ed9d02e382b34818e88b88a309c7fe71e65f419d0000000000000000000000000000000000000000000000000000000000000003"
> web3.sha3(key, {"encoding": "hex"})
"0x29ecdbdf95c7f6ceec92d6150c697aa14abeb0f8595dd58d808842ea237d8494"
```
From the above example, the `<256 bit aligned key value>` is the ethereum account address that should be added to the voting map, ed9d02e382b34818e88b88a309c7fe71e65f419d, padded to 256bits. The `<256 bit variable index>` is the index(3) of the canVote mapping in the solidity [voting smart contract](https://github.com/jpmorganchase/quorum/blob/master/core/quorum/block_voting.sol#L42) padded to 256bits. The index is calculated based on the location of canVote:

* Period[] periods --> index 0
* uint public voteThreshold --> index 1
* uint public voterCount --> index 2
* mapping(address => bool) public canVote --> index 3

The `genesis.json` file can be found in the `7nodes` folder in the `quorum-examples` repository.

### Setup Bootnode
Optionally you can set up a bootnode that all the other nodes will first connect to in order to find other peers in the network. You will first need to generate a bootnode key:
Optionally you can set up a bootnode that all the other nodes will first connect to in order to find other peers in the network. You will first need to generate a bootnode key:

1- To generate the key for the first time:

Expand All @@ -115,9 +58,9 @@ Optionally you can set up a bootnode that all the other nodes will first connect
2- To later restart the bootnode using the same key (and hence use the same enode url):

`bootnode -nodekey tmp_file.txt`

or

`bootnode -nodekeyhex 77bd02ffa26e3fb8f324bda24ae588066f1873d95680104de5bc2db9e7b2e510 // Key from tmp_file.txt`


Expand All @@ -127,44 +70,12 @@ Starting a node is as simple as `geth`. This will start the node without any of

`geth --bootnodes $BOOTNODE_ENODE`

### Voting role

Start a node with the voting role:

```
geth --voteaccount 0xed9d02e382b34818e88b88a309c7fe71e65f419d
```

Optionally the `--votepassword` can be used to unlock the account.
If this flag is omitted the node will prompt for the password.

### Block maker role

Start a node with the block maker role:
```
geth --blockmakeraccount 0x9186eb3d20cbd1f5f992a950d808c4495153abd5
```

Created blocks will be signed with this account.

Optionally the `--blockmakerpassword` can be used to unlock the account.
If this flag is omitted the node will prompt for the password.

## Setup multi-node network

Quorum comes with several scripts to setup a private test network with 7 nodes:

* node 1, has no special roles
* node 2, has the block maker role
* node 3, has no special roles
* node 4, has the voting role
* node 5, has the voting role
* node 6, has no special roles

All scripts can be found in the `7nodes` folder in the `quorum-examples` repository.
Quorum comes with several scripts to setup a private test network with 7 nodes in the `7nodes` folder in the `quorum-examples` repository.

1. Step 1, run `init.sh` and initialize data directories (change variables accordingly)
2. Step 2, start nodes with `start.sh` (change variables accordingly)
1. Step 1, run `raft-init.sh` and initialize data directories (change variables accordingly)
2. Step 2, start nodes with `raft-start.sh` (change variables accordingly)
3. Step 3, stop network with `stop.sh`

## Permissioned Network
Expand Down

0 comments on commit 37ccab5

Please sign in to comment.