permission: minor fixes and update with master

This commit is contained in:
Trung Nguyen 2019-09-04 14:39:53 -04:00
commit a5c8e7af32
No known key found for this signature in database
GPG Key ID: 4636434ED9505EB7
28 changed files with 468 additions and 96 deletions

View File

@ -270,9 +270,6 @@ var AppHelpFlagGroups = []flagGroup{
utils.MinerLegacyEtherbaseFlag,
utils.MinerLegacyExtraDataFlag,
},
},
{
Name: "MISC",
}, {
Name: "ISTANBUL",
Flags: []cli.Flag{
@ -280,6 +277,9 @@ var AppHelpFlagGroups = []flagGroup{
utils.IstanbulBlockPeriodFlag,
},
},
{
Name: "MISC",
},
}
// byCategory sorts an array of flagGroup by Name in the order

View File

@ -302,7 +302,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
}
limit := parent.GasLimit / params.OriginalGasLimitBoundDivisor
if uint64(diff) >= limit || header.GasLimit < params.OriginnalMinGasLimit {
if uint64(diff) >= limit || header.GasLimit < params.OriginalMinGasLimit {
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
}
// Verify that the block number is parent's +1

View File

@ -1271,9 +1271,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
if err := WritePrivateStateRoot(bc.db, block.Root(), privateStateRoot); err != nil {
return i, events, coalescedLogs, err
}
// /Quorum
allReceipts := mergeReceipts(receipts, privateReceipts)
// /Quorum
proctime := time.Since(bstart)

View File

@ -588,6 +588,8 @@ func (env *EVM) Push(statedb StateDB) {
// Quorum : the read only depth to be set up only once for the entire
// op code execution. This will be set first time transition from
// private state to public state happens
// statedb will be the state of the contract being called.
// if a private contract is calling a public contract make it readonly.
if !env.quorumReadOnly && env.privateState != statedb {
env.quorumReadOnly = true
env.readOnlyDepth = env.currentStateDepth

View File

@ -207,10 +207,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// Get the memory location of pc
op = contract.GetOp(pc)
if in.evm.quorumReadOnly && op.isMutating() {
return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited")
}
if in.cfg.Debug {
// Capture pre-execution values for tracing.
logged, pcCopy, gasCopy = false, pc, contract.Gas
@ -222,6 +218,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
if !operation.valid {
return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
}
if in.evm.quorumReadOnly && operation.writes {
return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited")
}
if err := operation.validateStack(stack); err != nil {
return nil, err
}

View File

@ -538,13 +538,3 @@ var stringToOp = map[string]OpCode{
func StringToOp(str string) OpCode {
return stringToOp[str]
}
func (op OpCode) isMutating() bool {
switch op {
// TODO(joel): REVERT?
case SELFDESTRUCT, CREATE, SSTORE, LOG0, LOG1, LOG2, LOG3, LOG4:
return true
default:
return false
}
}

View File

@ -0,0 +1,30 @@
??? question "How do I call contracts or send Transactions to existing contracts?"
The "Sandbox" tab provides the ability to load up a contract that has been deployed using Cakeshop or the Cakeshop APIs and to make Read calls or submit Transactions to those contracts.
??? question "How do I find existing contracts?"
The "Contracts" explorer tab lists all contracts that have been deployed using Cakeshop sandbox.
??? question "How do I deploy contracts to my network using Cakeshop?"
The "Sandbox" tab provides the ability to write and deploy contracts onto your chain.
??? question "How do I run Cakeshop on any Ethereum build or on my private Ethereum network?"
See the [Attach Mode](../Getting Started#attach-mode) instructions for using Cakeshop with your Ethereum-like node. This provides you the ability to start Cakeshop without auto-starting a geth node, and then attach it to your already-running node.
??? question "How do I run Cakeshop on many nodes?"
See the [Multi-Instance](../Getting Started#multi-instance-setup) instructions for managing multiple nodes that you control on an Ethereum-based network.
??? question "How do I save the solidity files that I have written in the Sandbox?"
You can't explicitly save these files at the moment, but they are auto-saved to your browser cache. For this reason, you shouldn't use Cakeshop as your version management system and you should definitely ensure you save them in a proper VCS outside of Cakeshop.
??? question "What is an 'Ethereum-like' ledger/node?"
An 'Ethereum-like' ledger/node is one that uses the Ethereum JSON RPC API. The Ethereum clients and [Quorum](https://github.com/jpmorganchase/quorum) are examples.
Note that if an Ethereum-forked ledger forks too far away from base Ethereum then there may be some issues with using Cakeshop on top of it.</em>

View File

@ -0,0 +1,147 @@
## Quickstart
### Requirements
* Java 8+
* Java app server (Tomcat, Jetty, etc) [Optional]
### Running via Spring Boot
* Download WAR file (Binary packages are available for macOS, Windows, and Linux platforms on the [releases](https://github.com/jpmorganchase/cakeshop/releases) page.
)
* Run `java -jar cakeshop.war`
* Navigate to [http://localhost:8080/](http://localhost:8080/)
*Note: when running in Windows, -Dgeth.node=geth must be specified as Quorum is not yet available on Windows OS*
### Running via App Server
* Download WAR file
* Put in `/webapps` folder of your app server
* Add Java system property `-Dspring.profiles.active=local` to startup script (`setenv.sh` for tomcat)
* Start app server
* Navigate to [http://localhost:8080/](http://localhost:8080/) (default port is usually 8080)
*Note: when running in Windows, -Dgeth.node=geth must be specified as Quorum is not yet available on Windows OS*
### Running modes
There are a few ways in which you can run Cakeshop (see the sections below for details on each, as well as [configuration](https://github.com/jpmorganchase/cakeshop/blob/master/docs/configuration.md#geth) page):
1. **Default mode**: _Used when you want Cakeshop to start up an Ethereum node._
Running Cakeshop in the Default mode will start up Cakeshop and also start running a regular geth node (on a private/test network).
2. **'Attach/Unmanaged' mode**: _Used when you want to attach Cakeshop to an already running Ethereum-like node._
Running Cakeshop in 'Attach' a.k.a 'unmanaged' mode will initialize Cakeshop but not start it nor start any Ethereum node. Once Cakeshop initialization is complete you can configure it to use the RPC details of your running node . When you then start Cakeshop it will attach to your node.
NOTE: if different parties on the network are using Cakeshop to deploy contracts to the network then they need to ensure they are using the same ContractRegistry address. See details below for setting up the ContractRegistry address in this case.
3. **Multi-Instance Set Up**: _Used when you want to run Cakeshop on more than one node in your network._
Cakeshop is currently designed such that a given instance of Cakeshop works directly with a single Ethereum-like node, however you can set up multiple instances of Cakeshop on the same machine (each which could either have been started in 'Default' mode or 'Attach' mode) such that each can talk to a different node.
NOTE: you can use the Attach mode and/or Multi-Instance setup configuration to run Cakeshop on [Quorum](https://github.com/jpmorganchase/quorum) nodes. See below for connecting Cakeshop to the [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) network from the quorum-examples repo.
#### The below commands assume you have renamed the WAR file to cakeshop.war
### Default Mode
1. In a terminal window run:
```
$ cd path/to/cakeshop/war
$ java -jar cakeshop.war
```
2. Open **http://localhost:8080/** in your browser (Firefox/Chrome supported)
### Attach Mode
1. In a terminal window run:
```
$ cd path/to/cakeshop/war
# The 'example' arg below will unpack the war file and set up the cakeshop data folders but will not actually start a node
$ java -jar cakeshop.war example
```
2. Navigate to path/to/cakeshop/war/data/local
3. Make the following edits to the application.properties file:
* set `geth.url` to the `rpcport` of your ethereum node, i.e. if your geth `rpcport` is 22001 then `geth.url=http\://localhost\:22001`
* ensure `geth.auto.start` is set to `false`
* ensure `geth.auto.stop` is set to `false`
4. Run:
```
$ java -jar cakeshop.war
```
5. Open **http://localhost:8080/** in your browser (Firefox/Chrome supported)
### Multi-Instance Setup
Although Cakeshop currently has a one-to-one mapping with the underlying Ethereum-like node that it connects to, it is possible to have multiple Cakeshop instances running on the same machine, each connecting to a different Ethereum-like node. The best way to achieve this is to create separate Cakeshop folders for each node and then attach to each separately. You should also configure the ContractRegistry address as per the below:
> ** Cakeshop ContractRegistry contract**
>Cakeshop deploys a ContractRegistry contract upon start up that is used to track those contracts that have been deployed to the chain using Cakeshop or the Cakeshop APIs. When running a multi-instance setup, you'll want to ensure that each instance of Cakeshop references the same ContractRegistry contract in order that each provides a consistent view within the Contracts Explorer.
>There are two cmd flags that can be set to achieve this:
> * `CAKESHOP_SHARED_CONFIG` (<em>recommended</em>): When this flag is set, Cakeshop will try to load a file called 'shared.properties' and read the ContractRegistry address from it. If the file doesn't exist, Cakeshop will deploy the ContractRegistry contract, create this file and store the address in the file.
> USAGE: `$ CAKESHOP_SHARED_CONFIG="{fileLocation}" java -jar cakeshop.war`
> * `CAKESHOP_REGISTRY_ADDR`: This flag will directly override whatever ContractRegistry address is configured (or not) and run with that address. Using this flag doesn't change any local Cakeshop settings nor save this address to file and so you would have to run with this flag again to use this address again.
> USAGE: `$ CAKESHOP_REGISTRY_ADDR="0xabcdefgh.." java -jar cakeshop.war`
1. In terminal window 1 run:
```
mkdir myNetwork && cd myNetwork
cp path/to/cakeshop/download /myNetwork
cd myNetwork
mkdir node1 node2
cd node1
CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war example
```
2. Assuming you want to attach to an existing node, navigate to /myNetwork/node1/ and edit **application.properties** per the instructions for [attach mode](#attach-mode) as described above
3. In terminal window 2 run:
```
cd myNetwork/node2
CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war example
```
4. Navigate to myNetwork/node2 and edit **application.properties** per the instructions for [attach mode](#attach-mode) as described above
5. In terminal window 1 run:
```
CAKESHOP_SHARED_CONFIG=".." java -jar ../cakeshop.war
```
6. In terminal window 2 run:
```
CAKESHOP_SHARED_CONFIG=".." java -Dserver.port=8081 -jar cakeshop.war # Cakeshop will now be available on localhost:8081
```
7. In browser window 1 open http://localhost:8080/
8. In browser window 2 open http://localhost:8081/
### Running Cakeshop on quorum-examples
You can use the 'Attach' mode to use Cakeshop to explore the quorum-examples [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) network.
To do so:
1. Follow the instructions in the [7nodes](https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes) example to start the 7nodes network (running vagrant up, init.sh, start.sh etc.)
2. Follow the instructions listed under the [Attach](#attach-mode) mode as described above, using the `rpcport` of the node you want to explore as found in the 7nodes [start.sh](https://github.com/jpmorganchase/quorum-examples/blob/master/examples/7nodes/start.sh) file. Equally, follow the [Multi-Instance](#multi-instance-setup) setup to attach to more than one of the Quorum nodes.
### Confirming Cakeshop Start Up
In all cases, Cakeshop will be running once you see the below image, which shows the Cakeshop build and url that you can access that instance of Cakeshop on:
![image](https://raw.githubusercontent.com/jpmorganchase/cakeshop-docs/master/images/happylion.png)

21
docs/Cakeshop/Overview.md Normal file
View File

@ -0,0 +1,21 @@
## What is it?
[Cakeshop](https://github.com/jpmorganchase/cakeshop) is a set of tools and APIs for working with [Ethereum](https://ethereum.org/)-like ledgers, packaged as a Java web application archive (WAR) that gets you up and running in under 60 seconds.
Cakeshop can either start up a geth node, which you can then interact with using the Cakeshop front-end, or it can be connected to an Ethereum-like node, such as Quorum, that you already have running. A given Cakeshop instance connects with one node on the blockchain network you connect to.
![image](console.png)
Out of the box you get:
* **Node Management** - Fully functioning Ethereum node (via geth), setting up a cluster
* **Blockchain Explorer** - view transactions, blocks and contracts, and see historical contract state at a point in time
* **Admin Console** - start & stop nodes, create a cluster and view the overall status of your network
* **Peer Management** - easily discover, add and remove peers
* **Solidity Sandbox** - develop, compile, deploy and interact with Solidity smart contracts
It provides tools for managing a local blockchain node, setting up clusters,
exploring the state of the chain, and working with contracts.
The Cakeshop package includes the [tessera](https://github.com/jpmorganchase/tessera) and [constellation](https://github.com/jpmorganchase/constellation) transaction managers, a [Solidity](https://solidity.readthedocs.org/en/latest/) compiler, and all dependencies. Cakeshop will download the latest version of [quorum](https://github.com/jpmorganchase/quorum) and bootnode from [geth](https://github.com/ethereum/go-ethereum) (to use a different version, see [here](docs/configuration.md#custom-quorum-binaries))

BIN
docs/Cakeshop/console.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

View File

@ -158,27 +158,4 @@ To add a node to the cluster, attach to a JS console and issue `raft.addPeer(eno
## FAQ
**Could you have a single- or two-node cluster? More generally, could you have an even number of nodes ?**
A cluster can tolerate failures that leave a quorum (majority) available. So a cluster of two nodes can't tolerate any failures, three nodes can tolerate one, and five nodes can tolerate two. Typically Raft clusters have an odd number of nodes, since an even number provides no failure tolerance benefit.
**What happens if you don't assume minter and leader are the same node?**
There's no hard reason they couldn't be different. We just co-locate the minter and leader as an optimization.
* It saves one network call communicating the block to the leader.
* It provides a simple way to choose a minter. If we didn't use the Raft leader we'd have to build in "minter election" at a higher level.
Additionally there could even be multiple minters running at the same time, but this would produce contention for which blocks actually extend the chain, reducing the productivity of the cluster (see "races" above).
**I thought there were no forks in a Raft-based blockchain. What's the deal with "speculative minting"?**
"Speculative chains" are not forks in the blockchain. They represent a series ("chain") of blocks that have been sent through Raft, after which each of the blocks may or may not actually end up being included in *the blockchain*.
**Can transactions be reversed? Since raft log entries can be disregarded as "no-ops", does this imply transaction reversal?**
No. When a Raft log entry containing a new block is disregarded as a "no-op", its transactions will remain in the transaction pool, and so they will be included in a future block in the chain.
**What's the deal with the block timestamp being stored in nanoseconds (instead of seconds, like other consensus mechanisms)?**
With raft-based consensus we can produce far more than one block per second, which vanilla Ethereum implicitly disallows (as the default timestamp resolution is in seconds and every block must have a timestamp greater than its parent). For Raft, we store the timestamp in nanoseconds and ensure it is incremented by at least 1 nanosecond per block.
Answers to frequently asked questions can be found on the main [Quorum FAQ page](../FAQ.md).

View File

@ -1,3 +1,5 @@
### Quorum FAQ
??? question "I've run into an issue with Quorum, where do I get support?"
The [Quorum Slack channels](https://clh7rniov2.execute-api.us-east-1.amazonaws.com/Express/) are the best place to query the community and get immediate help.
@ -38,9 +40,6 @@
??? question "Can I create a network of Quorum nodes using different consensus mechanisms?"
Unfortunately, that is not possible. Quorum nodes configured with raft will only be able to work correctly with other nodes running raft consensus. This applies to all other supported consensus algorithms.
??? info "Known Raft consensus node misconfiguration"
Please see https://github.com/jpmorganchase/quorum/issues/410
??? info "Quorum version compatibility table"
| | Adding new node v2.0.x | Adding new node v2.1.x | Adding new node v2.2.x |
| ----------------------------------- | ---------------------- | ---------------------- | ---------------------- |
@ -48,4 +47,34 @@
| Existing chain consisting of v2.1.x | <span style="color:red;">block sync</span> | <span style="color:green;">block sync<br /> public txn<br /> private txn</span> | <span style="color:green;">block sync<br /> public txn<br /> private txn</span> |
| Existing chain consisting of v2.2.x | <span style="color:red;">block sync</span> | <span style="color:green;">block sync<br /> public txn<br /> private txn</span> | <span style="color:green;">block sync<br /> public txn<br /> private txn</span> |
**Note:** While every Quorum v2 client will be able to connect to any other v2 client, the usefullness will be severely degraded. <span style="color:red;">Red color</span> signifies that while connectivity is possible, <span style="color:red;">red colored</span> versions will be unable to send public or private txns to the rest of the net due to the EIP155 changes in the signer implemented in newer versions.
**Note:** While every Quorum v2 client will be able to connect to any other v2 client, the usefullness will be severely degraded. <span style="color:red;">Red color</span> signifies that while connectivity is possible, <span style="color:red;">red colored</span> versions will be unable to send public or private txns to the rest of the net due to the EIP155 changes in the signer implemented in newer versions.
### Raft FAQ
??? question "Could you have a single- or two-node cluster? More generally, could you have an even number of nodes?"
A cluster can tolerate failures that leave a quorum (majority) available. So a cluster of two nodes can't tolerate any failures, three nodes can tolerate one, and five nodes can tolerate two. Typically Raft clusters have an odd number of nodes, since an even number provides no failure tolerance benefit.
??? question "What happens if you don't assume minter and leader are the same node?"
There's no hard reason they couldn't be different. We just co-locate the minter and leader as an optimization.
* It saves one network call communicating the block to the leader.
* It provides a simple way to choose a minter. If we didn't use the Raft leader we'd have to build in "minter election" at a higher level.
Additionally there could even be multiple minters running at the same time, but this would produce contention for which blocks actually extend the chain, reducing the productivity of the cluster (see "races" above).
??? question "I thought there were no forks in a Raft-based blockchain. What's the deal with "speculative minting"?"
"Speculative chains" are not forks in the blockchain. They represent a series ("chain") of blocks that have been sent through Raft, after which each of the blocks may or may not actually end up being included in *the blockchain*.
??? question "Can transactions be reversed? Since raft log entries can be disregarded as "no-ops", does this imply transaction reversal?"
No. When a Raft log entry containing a new block is disregarded as a "no-op", its transactions will remain in the transaction pool, and so they will be included in a future block in the chain.
??? question "What's the deal with the block timestamp being stored in nanoseconds (instead of seconds, like other consensus mechanisms)?"
With raft-based consensus we can produce far more than one block per second, which vanilla Ethereum implicitly disallows (as the default timestamp resolution is in seconds and every block must have a timestamp greater than its parent). For Raft, we store the timestamp in nanoseconds and ensure it is incremented by at least 1 nanosecond per block.
??? question "Why do I see "Error: Number can only safely store up to 53 bits" when using web3js with Raft?"
As mentioned above, Raft stores the timestamp in nanoseconds, so it is too large to be held as a number in javascript.
You need to modify your code to take account of this. An example can be seen [here](https://github.com/jpmorganchase/quorum.js/blob/master/lib/index.js#L35).
A future quorum release will address this issue.
??? info "Known Raft consensus node misconfiguration"
Please see https://github.com/jpmorganchase/quorum/issues/410

View File

@ -50,7 +50,7 @@ issues with the version of curl bundled with Vagrant.
* If the machine you are using has less than 8 GB memory you will likely encounter system issues such as slow down and unresponsiveness when starting the Vagrant instance as your machine will not have the capacity to run the VM. There are several steps that can be taken to overcome this:
1. Shutdown any running processes that are not required
1. If running the [7nodes example](../7Nodes), reduce the number of nodes started up. See the [7nodes: Reducing the number of nodes](../7Nodes#reducing-the-number-of-nodes) for info on how to do this.
1. If running the [7nodes example](../7Nodes), reduce the number of nodes started up. See the [7nodes: Reducing the number of nodes](../7Nodes-Setup#reducing-the-number-of-nodes) for info on how to do this.
1. Set up and run the examples locally. Running locally reduces the load on your memory compared to running in Vagrant.
### Running with Docker

View File

@ -5,7 +5,7 @@ This section details easy to follow step by step instructions of how to setup on
Let's go through step by step instructions to setup a Quorum node with Raft consensus.
## Quorum with Raft consensus
1. On each machine build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and bootnode
1. On each machine build Quorum as described in the [Installing](../Installing) section. Ensure that PATH contains geth and bootnode
```
$ git clone https://github.com/jpmorganchase/quorum.git
$ cd quorum
@ -296,7 +296,7 @@ Let's go through step by step instructions to setup a Quorum node with Raft cons
## Quorum with Istanbul BFT consensus
1. On each machine build Quorum as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and boot node
1. On each machine build Quorum as described in the [Installing](../Installing) section. Ensure that PATH contains geth and boot node
```
$ git clone https://github.com/jpmorganchase/quorum.git
$ cd quorum
@ -902,7 +902,7 @@ Just execute **step 4** instruction from removing a validator node.
## Adding privacy transaction manager
### Tessera
1. Build Quorum and install [Tessera](https://github.com/jpmorganchase/tessera/releases) as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth and bootnode. Be aware of the location of the `tessera.jar` release file
1. Build Quorum and install [Tessera](https://github.com/jpmorganchase/tessera/releases) as described in the [Installing](../Installing) section. Ensure that PATH contains geth and bootnode. Be aware of the location of the `tessera.jar` release file
```
$ git clone https://github.com/jpmorganchase/quorum.git
$ cd quorum
@ -1156,7 +1156,7 @@ Just execute **step 4** instruction from removing a validator node.
```
### Constellation
1. Build Quorum and install [Constellation](https://github.com/jpmorganchase/constellation/releases) as described in the [getting set up](../Setup%20Overview%20%26%20Quickstart) section. Ensure that PATH contains geth, bootnode, and constellation-node binaries
1. Build Quorum and install [Constellation](https://github.com/jpmorganchase/constellation/releases) as described in the [Installing](../Installing) section. Ensure that PATH contains geth, bootnode, and constellation-node binaries
2. Generate new keys with `constellation-node --generatekeys=new-node-1`
3. Start your constellation node and send it into background with `constellation-node --url=https://127.0.0.1:9001/ --port=9001 --workdir=. --socket=tm.ipc --publickeys=new-node-1.pub --privatekeys=new-node-1.key --othernodes=https://127.0.0.1:9001/ >> constellation.log 2>&1 &`
4. Start your node and send it into background with `PRIVATE_CONFIG=tm.ipc nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 2>>node.log &`

View File

@ -62,21 +62,22 @@ web3.eth.sendRawPrivateTransaction(signedTransactionData [, privateData] [, call
Sends a pre-signed transaction. For example can be signed using: https://github.com/SilentCicero/ethereumjs-accounts
__Important:__ Please note that before calling this API, a `storeraw` api need to be called first to Quorum's private transaction manager. Instructions on how to do this can be found [here](https://github.com/jpmorganchase/tessera/wiki/Interface-&-API).
__Important:__ Please note that before calling this API, a `storeraw` api need to be called first to Quorum's private transaction manager. Instructions on how to do this can be found [here](../../Privacy/Tessera/Usage/Interface%20&%20API/).
##### Parameters
1. `String` - Signed transaction data in HEX format
2. `Object` - Private data to send
- `privateFor`: `List<String>` - When sending a private transaction, an array of the recipients' base64-encoded public keys.
3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous. See [this note](#using-callbacks) for details.
3. `Function` - (optional) If you pass a callback the HTTP request is made asynchronous.
##### Returns
##### Returns
`String` - The 32 Bytes transaction hash as HEX string.
If the transaction was a contract creation use [web3.eth.getTransactionReceipt()](#web3ethgettransactionreceipt) to get the contract address, after the transaction was mined.
If the transaction was a contract creation use `web3.eth.getTransactionReceipt()` to get the contract address, after the transaction was mined.
##### Example
```js
##### Example
```js
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')
var rawTx = {
@ -97,7 +98,7 @@ __Important:__ Please note that before calling this API, a `storeraw` api need t
if (!err)
console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385"
});
```
```

View File

@ -171,7 +171,7 @@ Any additions to the `permissioned-nodes.json` file will be dynamically picked u
Removing existing connected nodes from the `permissioned-nodes.json` file will not immediately drop those existing connected nodes. However, if the connection is dropped for any reason, and a subsequent connect request is made from the dropped node ids, it will be rejected as part of that new request.
## Quorum API
Please see the [Quorum API](../../api) page for details.
Please see the [Quorum API](../api) page for details.
## Network and Chain ID
@ -192,6 +192,7 @@ In Quorum, transactions are considered private if the `v` parameter is set to `3
If you are running a version prior to version 2.1.0, EIP-155 signing is not used, thus a chain ID of `1` was allowed; you will need to change this using `geth init` before running an updated version.
# Zero Knowledge Work
## ZSL Proof of Concept
J.P. Morgan and the Zcash team partnered to create a proof of concept (POC) implementation of ZSL for Quorum, which enables the issuance of digital assets using ZSL-enabled public smart contracts (z-contracts). We refer to such digital assets as “z-tokens”. Z-tokens can be shielded from public view and transacted privately. Proof that a shielded transaction has been executed can be presented to a private contract, thereby allowing the private contract to update its state in response to shielded transactions that are executed using public z-contracts.
@ -200,6 +201,15 @@ This combination of Constellation/Tesseras private contracts with ZSLs z-c
For more information, see the [ZSL](../../ZSL) page of this wiki.
## Anonymous Zether
This is a private payment system, an _anonymous_ extension of Bünz, Agrawal, Zamani and Boneh's [Zether protocol](https://crypto.stanford.edu/~buenz/papers/zether.pdf).
The outlines of an anonymous approach are sketched in the authors' original manuscript. We develop an explicit proof protocol for this extension, described in the technical note [AnonZether.pdf](https://github.com/jpmorganchase/anonymous-zether/blob/master/docs/AnonZether.pdf). We also provide a full implementation of the anonymous protocol (including a proof generator, verification contracts, and a client / front-end).
For more information, see the [Anonymous Zether](https://github.com/jpmorganchase/anonymous-zether/) repo.
# Quorum Genesis Options
## Configurable transaction size:
Quorum allows operators of blockchains to increase maximum transaction size of accepted transactions via the genesis block. The Quorum default is currently increased to `64kb` from Ethereum's default `32kb` transaction size. This is configurable up to `128kb` by adding `txnSizeLimit` to the config section of the genesis file:
@ -213,3 +223,15 @@ Quorum allows operators of blockchains to increase maximum transaction size of a
}
```
## Contract code size:
Quorum allows operators of blockchains to increase maximum contract code size of accepted smart contracts via the genesis block. The Quorum default is currently increased to `32kb` from Ethereum's default `24kb` contract code size. This is configurable up to `128kb` by adding `maxCodeSize` to the config section of the genesis file:
``` json
"config": {
"chainId": 10,
"isQuorum":true.
...
"maxCodeSize": 128
}
```

View File

@ -181,3 +181,17 @@ It is possible to configure a node that will be sent a copy of every transaction
---
### Remote-Key-Validation
Tessera provides an API `/partyinfo` on Tessera P2P server to discover all the peers in the network. In order to prevent attackers trying to inject malicious addresses against public keys, where they will try to assign the address to direct private transactions to them instead of the real owner of the key, we have added a feature to enable node level validation on the remote key that checks the remote node does in fact own the keys that were advertised. Only after the keys are validated with the remote node to ensure they own them, the keys are added to the local network info (partyinfo) store.
Default configuration for this is `false` as this is BREAKABLE change to lower versions to Tessera 0.10.0. To enable this, simple set below parameter to true in the configuration:
```
"features": {
"enableRemoteKeyValidation": true
}
```
---

View File

@ -4,6 +4,8 @@ Tessera configuration varies by version as new features are added or changed. Be
| Version |
| ------------- |
| [0.9 - latest release](../Tessera%20v0.9%20sample%20settings) |
| [0.10 - latest release](../Tessera%20v0.10.0%20sample%20settings) |
| [0.9](../Tessera%20v0.9%20sample%20settings) |
| [0.8](../Tessera%20v0.8%20sample%20settings) |
| [0.7.3](../Tessera%20v0.7.3%20sample%20settings) |

View File

@ -0,0 +1,139 @@
**Changes:**
- Added configuration for remote key validation.Default is set to false
e.g.
```json
"unixSocketFile": "Path",
"features": {
"enableRemoteKeyValidation": false
}
```
**Sample:**
```json
{
"useWhiteList": "boolean",
"jdbc": {
"url": "String",
"username": "String",
"password": "String"
},
"serverConfigs": [
{
"app": "ENCLAVE",
// Defines us using a remote enclave, leave out if using built-in enclave
"enabled": true,
"serverAddress": "http://localhost:9081",
//Where to find the remote enclave
"communicationType": "REST"
},
{
"app": "ThirdParty",
"enabled": true,
"serverAddress": "http://localhost:9081",
"bindingAddress": "String - url with port e.g. http://127.0.0.1:9081",
"communicationType": "REST"
},
{
"app": "Q2T",
"enabled": true,
"serverAddress": "unix:/tmp/tm.ipc",
"communicationType": "REST"
},
{
"app": "P2P",
"enabled": true,
"serverAddress": "http://localhost:9001",
"bindingAddress": "String - url with port e.g. http://127.0.0.1:9001",
"sslConfig": {
"tls": "enum STRICT,OFF",
"generateKeyStoreIfNotExisted": "boolean",
"serverKeyStore": "Path",
"serverTlsKeyPath": "Path",
"serverTlsCertificatePath": "Path",
"serverKeyStorePassword": "String",
"serverTrustStore": "Path",
"serverTrustCertificates": [
"Path..."
],
"serverTrustStorePassword": "String",
"serverTrustMode": "Enumeration: CA, TOFU, WHITELIST, CA_OR_TOFU, NONE",
"clientKeyStore": "Path",
"clientTlsKeyPath": "Path",
"clientTlsCertificatePath": "Path",
"clientKeyStorePassword": "String",
"clientTrustStore": "Path",
"clientTrustCertificates": [
"Path..."
],
"clientTrustStorePassword": "String",
"clientTrustMode": "Enumeration: CA, TOFU, WHITELIST, CA_OR_TOFU, NONE",
"knownClientsFile": "Path",
"knownServersFile": "Path"
},
"communicationType": "REST"
}
],
"peer": [
{
"url": "url e.g. http://127.0.0.1:9000/"
}
],
"keys": {
"passwords": [
"String..."
],
"passwordFile": "Path",
"azureKeyVaultConfig": {
"url": "Azure Key Vault url"
},
"hashicorpKeyVaultConfig": {
"url": "Hashicorp Vault url",
"approlePath": "String (defaults to 'approle' if not set)",
"tlsKeyStorePath": "Path to jks key store",
"tlsTrustStorePath": "Path to jks trust store"
},
"keyData": [
{
"config": {
"data": {
"aopts": {
"variant": "Enum : id,d or i",
"memory": "int",
"iterations": "int",
"parallelism": "int"
},
"bytes": "String",
"snonce": "String",
"asalt": "String",
"sbox": "String",
"password": "String"
},
"type": "Enum: argon2sbox or unlocked. If unlocked is defined then config data is required. "
},
"privateKey": "String",
"privateKeyPath": "Path",
"azureVaultPrivateKeyId": "String",
"azureVaultPrivateKeyVersion": "String",
"publicKey": "String",
"publicKeyPath": "Path",
"azureVaultPublicKeyId": "String",
"azureVaultPublicKeyVersion": "String",
"hashicorpVaultSecretEngineName": "String",
"hashicorpVaultSecretName": "String",
"hashicorpVaultSecretVersion": "Integer (defaults to 0 (latest) if not set)",
"hashicorpVaultPrivateKeyId": "String",
"hashicorpVaultPublicKeyId": "String"
}
]
},
"alwaysSendTo": [
"String..."
],
"unixSocketFile": "Path",
"features": {
"enableRemoteKeyValidation": false
}
}
```

View File

@ -6,23 +6,24 @@ Below is a description of how Private Transactions are processed in Quorum:
In this example, Party A and Party B are party to Transaction AB, whilst Party C is not.
1. Party A sends a Transaction to their Quorum Node, specifying the Transaction payload and setting `privateFor` to be the public keys for Parties A and B
2. Party A's Quorum Node passes the Transaction on to its paired Transaction Manager, requesting for it to store the Transaction payload
3. Party A's Transaction Manager makes a call to its associated Enclave to validate the sender and encrypt the payload
4. Party A's Enclave checks the private key for Party A and, once validated, performs the Transaction conversion. This entails:
1. Party A sends a Transaction to their Quorum Node, specifying the Transaction payload and setting `privateFor` to be the public keys for Parties A and B (Party A is optional)
1. Party A's Quorum Node passes the Transaction on to its paired Transaction Manager, requesting for it to store the Transaction payload
1. Party A's Transaction Manager makes a call to its associated Enclave to validate the sender and encrypt the payload
1. Party A's Enclave checks the private key for Party A and, once validated, performs the Transaction conversion. This entails:
1. generating a symmetric key and a random Nonce
1. encrypting the Transaction payload and Nonce with the symmetric key from i.
1. calculating the SHA3-512 hash of the encrypted payload from ii.
1. iterating through the list of Transaction recipients, in this case Parties A and B, and encrypting the symmetric key from i. with the recipient's public key (PGP encryption)
1. returning the encrypted payload from step ii., the hash from step iii. and the encrypted keys (for each recipient) from step iv. to the Transaction Manager
5. Party A's Transaction manager then stores the encrypted payload (encrypted with the symmetric key) and encrypted symmetric key using the hash as the index, and then securely transfers (via HTTPS) the hash, encrypted payload, and encrypted symmetric key that has been encrypted with Party B's public key to Party B's Transaction Manager. Party B's Transaction Manager responds with an Ack/Nack response. Note that if Party A does not receive a response/receives a Nack from Party B then the Transaction will not be propagated to the network. It is a prerequisite for the recipients to store the communicated payload.
6. Once the data transmission to Party B's Transaction Manager has been successful, Party A's Transaction Manager returns the hash to the Quorum Node which then replaces the Transaction's original payload with that hash, and changes the transaction's `V` value to 37 or 38, which will indicate to other nodes that this hash represents a private transaction with an associated encrypted payload as opposed to a public transaction with nonsensical bytecode.
7. The Transaction is then propagated to the rest of the network using the standard Ethereum P2P Protocol.
8. A block containing Transaction AB is created and distributed to each Party on the network.
9. In processing the block, all Parties will attempt to process the Transaction. Each Quorum node will recognise a `V` value of 37 or 38, identifying the Transaction as one whose payload requires decrypting, and make a call to their local Transaction Manager to determine if they hold the Transaction (using the hash as the index to look up).
10. Since Party C does not hold the Transaction, it will receive a `NotARecipient` message and will skip the Transaction - it will not update its Private StateDB. Party A and B will look up the hash in their local Transaction Managers and identify that they do hold the Transaction. Each will then make a call to its Enclave, passing in the Encrypted Payload, Encrypted symmetric key and Signature.
11. The Enclave validates the signature and then decrypts the symmetric key using the Party's private key that is held in The Enclave, decrypts the Transaction Payload using the now-revealed symmetric key and returns the decrypted payload to the Transaction Manager.
12. The Transaction Managers for Parties A and B then send the decrypted payload to the EVM for contract code execution. This execution will update the state in the Quorum Node's Private StateDB only. NOTE: once the code has been executed it is discarded so is never available for reading without going through the above process.
1. generating a random master key (RMK) and a random Nonce
1. encrypting the Transaction payload with the nonce and RMK from step a.
1. iterating through the list of transaction recipients, in this case parties A and B, and encrypting the RMK from a. with the shared key derived from Party A's private key and the recipient's public key, along with another randomly generated nonce. Each encrypted RMK is unique for each recipient and will only be shared with the respective recipient along with encrypted payload.
1. returning the encrypted payload from step b. and all encrypted RMKs from step c. to the Transaction Manager
1. Party A's Transaction Manager calculates the SHA3-512 hash of the encrypted payload then stores the encrypted payload and encrypted RMKs against the hash in the database
1. Party A's Transaction Manager then securely transfers (via HTTPS) the encrypted payload, and RMK that has been encrypted with shared key from previous step 4.c, the nonce's to Party B's Transaction Manager. Party B's Transaction Manager responds with an Ack/Nack response. Note that if Party A does not receive a response/receives a Nack from Party B then the Transaction will not be propagated to the network. It is a prerequisite for the recipients to store the communicated payload.
1. Once the data transmission to Party B's Transaction Manager has been successful, Party A's Transaction Manager returns the hash to the Quorum Node which then replaces the Transaction's original payload with that hash, and changes the transaction's `V` value to 37 or 38, which will indicate to other nodes that this hash represents a private transaction with an associated encrypted payload as opposed to a public transaction with nonsensical bytecode.
1. The Transaction is then propagated to the rest of the network using the standard Ethereum P2P Protocol.
1. A block containing Transaction AB is created and distributed to each Party on the network.
1. In processing the block, all Parties will attempt to process the Transaction. Each Quorum node will recognise a `V` value of 37 or 38, identifying the Transaction as one whose payload requires decrypting, and make a call to their local Transaction Manager to determine if they hold the Transaction (using the hash as the index to look up).
1. Since Party C does not hold the Transaction, it will receive a `NotARecipient` message and will skip the Transaction - it will not update its Private StateDB. Party A and B will look up the hash in their local Transaction Managers and identify that they do hold the Transaction. Each will then make a call to its Enclave, passing in the Encrypted Payload, Encrypted symmetric key and Signature.
1. The Enclave validates the signature and then decrypts the symmetric key using the Party's private key that is held in The Enclave, decrypts the Transaction Payload using the now-revealed symmetric key and returns the decrypted payload to the Transaction Manager.
1. The Transaction Managers for Parties A and B then send the decrypted payload to the EVM for contract code execution. This execution will update the state in the Quorum Node's Private StateDB only. NOTE: once the code has been executed it is discarded so is never available for reading without going through the above process.

View File

@ -28,6 +28,7 @@ The following endpoints are advertised on this interface:
* `/push`
* `/resend`
* `/partyinfo`
* `/partyinfo/validate`
### Third Party - Public API
@ -89,6 +90,10 @@ The following endpoints are advertised on this API:
- GET: Request public keys/url of all known peer nodes.
- POST: accepts a stream that contains the caller node's network information, and returns a merged copy with the callee node's network information
**`partyinfo/validate`** - _Validates a node possesses a key_
- Will request a node to decrypt a transaction in order to prove that it has access to the private part of its advertised public key.
**`sendraw`** - _Send transaction bytestring_
- Send transaction payload bytestring from Quorum to Tessera node. Tessera sends the transaction hash in the response back.

View File

@ -219,14 +219,4 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
// more reliably update peers or the local TD state.
go pm.BroadcastBlock(head, false)
}
atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
// We've completed a sync cycle, notify all peers of new state. This path is
// essential in star-topology networks where a gateway node needs to notify
// all its out-of-date peers of the availability of a new block. This failure
// scenario will most often crop up in private and hackathon networks with
// degenerate connectivity, but it should be healthy for the mainnet too to
// more reliably update peers or the local TD state.
go pm.BroadcastBlock(head, false)
}
}

View File

@ -72,7 +72,11 @@ nav:
- How it works: Privacy/Constellation/How constellation works.md
- Sample Configuration: Privacy/Constellation/Sample Configuration.md
- Running Constellation: Privacy/Constellation/Installation & Running.md
- Product Roadmap: roadmap.md
- Cakeshop:
- Overview: Cakeshop/Overview.md
- Getting Started: Cakeshop/Getting started.md
- Cakeshop FAQ: Cakeshop/Cakeshop FAQ.md
- Product Roadmap: roadmap.md
- FAQ: FAQ.md
theme:

View File

@ -152,7 +152,7 @@ func TestParseNode(t *testing.T) {
if err == nil {
t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError)
continue
} else if err.Error() != test.wantError {
} else if !strings.Contains(err.Error(), test.wantError) {
t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError)
continue
}

View File

@ -139,7 +139,7 @@ func TestParseNode(t *testing.T) {
if err == nil {
t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError)
continue
} else if err.Error() != test.wantError {
} else if !strings.Contains(err.Error(), test.wantError) {
t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError)
continue
}

View File

@ -25,7 +25,7 @@ var (
const (
// these are original values from upstream Geth, used in ethash consensus
OriginnalMinGasLimit uint64 = 5000 // The bound divisor of the gas limit, used in update calculations.
OriginalMinGasLimit uint64 = 5000 // The bound divisor of the gas limit, used in update calculations.
OriginalGasLimitBoundDivisor uint64 = 1024 // Minimum the gas limit may ever be.
// modified values for Quorum

View File

@ -28,7 +28,7 @@ const (
QuorumVersionMajor = 2
QuorumVersionMinor = 2
QuorumVersionPatch = 4
QuorumVersionPatch = 5
)
// Version holds the textual version string.

View File

@ -2,8 +2,8 @@ package permission
import (
"crypto/ecdsa"
"errors"
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
@ -79,7 +79,7 @@ func setup() {
defer os.RemoveAll(ksdir)
if err != nil {
t.Fatal("failed to create keystore: %v\n", err)
t.Fatalf("failed to create keystore: %v\n", err)
}
nodeKey, _ := crypto.GenerateKey()
guardianKey, _ = crypto.GenerateKey()